线程安全和对应的核心概念
生活随笔
收集整理的這篇文章主要介紹了
线程安全和对应的核心概念
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
線程安全
- 線程安全的概念:當(dāng)多個線程訪問某一個類(對象和方法)時,這個類始終都能表現(xiàn)出正確的行為,那么這個類(對象或者方法)就是線程安全的
- synchronized:可以在任意對象及方法上加鎖,而加鎖的這段代碼稱為‘互斥區(qū)’或者“臨界區(qū)”
- 當(dāng)多個線程訪問myThread的run方法時,以排隊(duì)的方式進(jìn)行處理(這里排隊(duì)是按照CPU分配的先后順序而定的),一個線程想要實(shí)現(xiàn)synchronized裝飾的方法里的代碼,首先是嘗試獲取鎖,如果可以得到鎖,就可以執(zhí)行synchronized代碼體的內(nèi)容;如果拿不到鎖,這個線程就會不斷嘗試去獲取鎖資源,直到拿到為止;而且是多個線程同時去競爭這把鎖(鎖競爭)
Synchronized
- 同步Synchronized:同步的概念就是共享,如果不是共享的資源就沒有必要進(jìn)行同步
- 異步asynchronized:異步的概念就是獨(dú)立,相互之間不受到任何制約
- 同步的目的是為了保證線程的安全,對于線程安全需要保證兩個特性 原子性(同步)和可見性
線程之間通信
- 線程通信的概念:線程是操作系統(tǒng)中獨(dú)立的個體,但是這些個體如果不經(jīng)過特殊的處理就不能成為一個整體,線程之間的通信就成為整體的必用的方式之一。當(dāng)線程之間存在通信指揮,系統(tǒng)之間的交互性會更強(qiáng)大,在提高CPU利用率的同時還會使開發(fā)人員對于線程任務(wù)在處理過程中,進(jìn)行有效的把控和監(jiān)督
- 使用wait/notify方法實(shí)現(xiàn)線程之間的通信(這兩個方法都是object的類的方法,即java為所有的對象都提供了這兩個方法)
- wait和notify必須配合synchronized關(guān)鍵字使用
- wait方法釋放鎖/notify方法不釋放鎖
ThreadLocal概念
- 線程局部變量,是一種多線程間并發(fā)訪問變量的解決方案,與synchronized等加鎖的方式不同,ThreadLocal完全不提供鎖,而使用以空間換時間的手段,為每個線程提供變量的獨(dú)立副本,以保障線程的安全
- 從性能上說,ThreadLocal不具有絕對的優(yōu)勢,在并發(fā)不是很高的情況下,加鎖的性能可能會更好,但是作為一套與鎖完全無關(guān)的線程安全解決方案,在高并發(fā)量或者競爭激烈的場景,使用ThreadLocal可以在一定程度上減少鎖競爭
Volatile關(guān)鍵字核心概念與應(yīng)用
- Volatile:主要作用是使變量在多個線程之間可見
- 阻止指令的重排序,happens-before
- 一個線程可以執(zhí)行的操作有使用(use)、賦值(assign)、轉(zhuǎn)載(load)、存儲(store)、鎖定(lock)、解鎖(unlock)
- 主內(nèi)存可以執(zhí)行的操作有讀(read)、寫(write)、鎖定(lock)、解鎖(unlock),每個操作都是原子的
- volatile的作用就是強(qiáng)制線程到主內(nèi)存(共享內(nèi)存)里去讀取變量,而不是去線程工作內(nèi)存里去讀取,從而實(shí)現(xiàn)了多個線程之間變量的可見,也就是滿足線程安全的可見行
JVM
- Java Memory Model(Java內(nèi)存模型),簡稱JVM,用于解決線程對于共享變量的寫入何時對于另一個線程可見
- 所有變量都存儲在主內(nèi)存中,每一個線程都有一個私有的本地內(nèi)存,本地內(nèi)存是將該線程使用到的變量,從主內(nèi)存中拷貝到本地
- 線程對于變量的所有操作(讀取、賦值等)都必須在工作內(nèi)存中進(jìn)行,而不能直接讀寫主內(nèi)存中的變量(volatile變量也不例外)
- happens-before規(guī)則,例如操作A :i=1;操作B:j=i;如果操作Ahappens-before操作B,那么操作B完成之后,j的值一定為1;
- 因?yàn)閔appens-before關(guān)系可以向程序員保證,在操作B執(zhí)行之前,操作A的執(zhí)行后的影響【或者說明結(jié)果】(修改i的值)對于操作B是可以觀察到的【可見的】
規(guī)則
- 簡而言之,使用happens-before概念來闡述操作之間的內(nèi)存可見行
- 程序順序規(guī)則:一個線程中的每個操作,happens-before于該線程中的任意后續(xù)操作,也就是說,你寫的操作,如果是單線程執(zhí)行,那么前面的操作就會happens-before于后面的操作
- 監(jiān)視器鎖規(guī)則:對于一個鎖的解鎖,happens-before于隨后對這個鎖的加鎖
- Volatile變量規(guī)則:對于一個volatile域的寫,happens-before于任意后續(xù)對這個volatile域的讀
- 傳遞性規(guī)則:A happens-before B,B happens-before C,則A happens-before C
指令重排序
- 為了保證程序的最終運(yùn)行結(jié)果需要和在單線程嚴(yán)格意義的順序化環(huán)境下執(zhí)行的結(jié)果一致,程序指令的執(zhí)行順序有可能和代碼的順序不一致,這個過程就稱之為指令的重排序
- 指令的重排序的意義:JVM利用處理器的特性,充分利用多級緩存,多核等進(jìn)行適當(dāng)?shù)闹噶钪嘏判?#xff0c;從而可以充分利用CPU的執(zhí)行特點(diǎn),最大程度上發(fā)揮機(jī)器的性能
Atomic系列類比
- Atomic系列類封裝了一系列的基礎(chǔ)類型和對象操作,其目的是為了實(shí)現(xiàn)原子性
- AtomicInteger
- AtomicLong
- AtomicBoolean
- AtomicIntegerArray
- AtomicLongArray
- AtomicReference
- 注意:在對Atomic類操作的時候,如果有多個操作執(zhí)行,那么就是非原子性的,需要加aynchronized進(jìn)行修飾,保證Atomic類操作的整體原子性
總結(jié)
以上是生活随笔為你收集整理的线程安全和对应的核心概念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论文遇到的格式问题和修正方式
- 下一篇: 基于属性加密的ABE算法的应用场景思考展