鎖
synchronized 原子性
不可中斷鎖犬绒,適合競(jìng)爭(zhēng)不激烈,可讀性好
修改代碼塊:大括號(hào)括起來(lái)的代碼徒探,作用于調(diào)用的對(duì)象
修飾方法:整個(gè)方法葬荷,作用于調(diào)用的對(duì)象
修飾靜態(tài)方法:整個(gè)靜態(tài)方法,作用于所有對(duì)象
-
修飾類:括號(hào)括起來(lái)的部分岖寞,作用于所有對(duì)象
代碼塊和方法屬于同一類(交替打印數(shù)字問(wèn)題)抡四,靜態(tài)方法和類屬于同一類(打印完一個(gè)后在打印第二個(gè))
Lock
- 可中斷鎖,多樣化同步仗谆,適合競(jìng)爭(zhēng)時(shí)能維持常態(tài)
Atomic
- 競(jìng)爭(zhēng)激烈時(shí)也能維持常態(tài)指巡,比Lock性能好;只能同步一個(gè)值
可見(jiàn)性
導(dǎo)致共享變量在線程間不可見(jiàn)的原因
- 線程交叉執(zhí)行
- 重排序結(jié)合線程交叉執(zhí)行
- 共享變量更新后的值沒(méi)有在工作內(nèi)存與主內(nèi)存間及時(shí)更新
JMM關(guān)于synchronized的兩條規(guī)定
- 線程解鎖前隶垮,必須把共享內(nèi)存的最新值刷新到主內(nèi)存
- 線程加鎖時(shí)藻雪,將清空工作內(nèi)存中共享變量的值,從而使用共享變量時(shí)需要從主內(nèi)存中重新讀取最新的值(注意:加鎖和解鎖是同一把鎖)
可見(jiàn)性-volatile
- 通過(guò)加入內(nèi)存屏障和禁止重排序優(yōu)化來(lái)實(shí)現(xiàn)
- 將volatile變量寫操作時(shí)岁疼,會(huì)在寫操作后加入一條store屏障指令阔涉,將本地內(nèi)存中的共享變量值刷新到主內(nèi)存
- 對(duì)volatile變量讀操作時(shí)缆娃,會(huì)在讀操作前加入一條load屏障指令,從主內(nèi)存中讀取共享變量
有序性
- java內(nèi)存模型中瑰排,允許編譯器和處理器對(duì)指令進(jìn)行重排序贯要,但是重排序過(guò)程不會(huì)影響到單線程程序的執(zhí)行,卻會(huì)影響到多線程并發(fā)執(zhí)行的正確性椭住。
- volatile崇渗、synchronized、lock
有序性-hanpens-before原則 (8個(gè)原則)
- 程序次序規(guī)則:一個(gè)線程內(nèi)京郑,按照代碼順序宅广,書寫在前面的操作先行發(fā)生與書寫在后面的操作
- 鎖定規(guī)則:一個(gè)unlock操作先行發(fā)生與后面對(duì)同一個(gè)鎖的lock操作(無(wú)論在單線程或者多線程中同一個(gè)鎖如果處于被鎖定狀態(tài),那么需要先unlock然后在進(jìn)行l(wèi)ock)
- volatile變量規(guī)則:對(duì)一個(gè)變量的寫操作先行發(fā)生與后面對(duì)這個(gè)變量的讀操作(如果一個(gè)線程先去寫一個(gè)變量些举,另一個(gè)線程也去讀取這個(gè)變量跟狱,那么應(yīng)該是寫入操作先行發(fā)生于讀操作)-- 內(nèi)存屏障
- 傳遞規(guī)則:如果操作A先行發(fā)生于操作B,而操作B又先行發(fā)生與操作C户魏,則可以得出操作A先行發(fā)生與操作C
- 線程啟動(dòng)規(guī)則:Thread對(duì)象的start()方法先行發(fā)生于此線程的每一個(gè)動(dòng)作
- 線程中斷原則:對(duì)線程interrupt()方法的調(diào)用先行發(fā)生于被中斷線程的代碼檢測(cè)到中斷事件的發(fā)生驶臊;
- 線程終結(jié)規(guī)則:線程中所有的操作都先行發(fā)生于線程的終止檢測(cè),我們可以通過(guò)Threa.join()方法結(jié)束叼丑、Thread.isAlive()的返回值手段檢測(cè)到線程已經(jīng)終止執(zhí)行关翎;
- 對(duì)象終結(jié)規(guī)則:一個(gè)對(duì)象的初始化完成先行發(fā)生于他的finalize()方法的開(kāi)始。