日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程技术点二

發(fā)布時間:2025/7/25 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程技术点二 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.Java線程之間的通信由Java內(nèi)存模型控制(JMM)。

JMM定義了線程和主內(nèi)存之間的抽象關(guān)系:線程之間的共享變量存儲在主內(nèi)存中,每個線程都有一個私有的本地內(nèi)存,本地內(nèi)存中存儲了該線程以讀/寫共享變量的副本。

2.先行發(fā)生原則(happens-before)

3.數(shù)據(jù)依賴性

如果兩個操作訪問同一個變量,且這兩個操作中有一個為寫操作,此時這兩個操作之間就存在數(shù)據(jù)依賴性。

數(shù)據(jù)依賴分為3種類型:寫后讀,寫后寫,讀后寫

編譯器和處理器在重排序時,會遵守數(shù)據(jù)依賴性,編譯器和處理器不會改變存在數(shù)據(jù)依賴關(guān)系的兩個操作的執(zhí)行順序。

4.as-if-serial語義

不管怎么重排序,(單線程)程序的執(zhí)行結(jié)果不能被改變。

5.JMM和順序一致性模型的差異

1)順序一致性模型保證單線程內(nèi)的操作會按照程序的順序執(zhí)行,而JMM模型不保證單線程內(nèi)的操作會按照程序的順序執(zhí)行(臨界區(qū)內(nèi)的重排序)

2)順序一致性模型保證所有線程只能看到一致的操作執(zhí)行順序,而JMM不保證所有線程能看到一致的操作執(zhí)行順序

3)JMM不保證對64位的long型和double型變量的寫操作具有原子性

6.volatile關(guān)鍵字

可以把對volatile變量的單個讀/寫看成是使用同一個鎖對這些單個讀/寫操作做了同步。

volatile變量自身具有下列特性

1)可見性:對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入

2)原子性:對任意單個volatile變量的讀/寫具有原子性,但類似于volatile++這種復(fù)合操作不具有原子性

7.volatile寫-讀的內(nèi)存語義

1)當(dāng)寫一個volatile變量時,JMM會把該線程對應(yīng)的本地內(nèi)存中的共享變量值刷新到主內(nèi)存

2)當(dāng)讀一個volatile變量時,JMM會把該線程對應(yīng)的本地內(nèi)存置為無效。線程接下來將從主內(nèi)存中讀取共享變量

8.重排序分為編譯器重排序和處理器重排序,為了實(shí)現(xiàn)volatile內(nèi)存語義,JMM會分別限制這兩種類型重排序類型。為了實(shí)現(xiàn)volatile的內(nèi)存語義,編譯器在生成字節(jié)碼時,會在指令序列中插入內(nèi)存屏障來禁止特定類型的處理器重排序。

9.鎖的釋放和獲取的內(nèi)存語義

當(dāng)線程釋放鎖時,JMM會把該線程對應(yīng)的本地內(nèi)存中的共享變量刷新到主內(nèi)存中。

當(dāng)線程獲取鎖時,JMM會把該線程對應(yīng)的本地內(nèi)存置為無效。從而使得被監(jiān)視器保護(hù)的臨界區(qū)代碼必須從主內(nèi)存中讀取共享變量。

10.雙重檢查鎖定的問題根源

instance = new Singleton()這行代碼可以分解為如下3行偽代碼

memory=allocate();//分配對象的內(nèi)存空間

ctorInstance(memory);//初始化對象

instance=memory;//設(shè)置instance指向剛分配的內(nèi)存地址

解決方案:將instance聲明為volatile型,就可以實(shí)現(xiàn)線程安全的延遲初始化。

11.隊列同步器

用來構(gòu)建鎖或者其他同步組件的基礎(chǔ)框架,它使用了一個int成員變量表示同步狀態(tài),通過內(nèi)置的FIFO隊列來完成資源獲取線程的排隊工作。

同步器的主要使用方式是繼承,子類通過繼承同步器并實(shí)現(xiàn)它的抽象方法來管理同步狀態(tài),在抽象方法的實(shí)現(xiàn)過程中通過同步器提供的3個方法對同步狀態(tài)進(jìn)行修改(getState()、setState(int newState)和compareAndSetState(int expect, int update))。

子類推薦被定義為自定義同步組件的靜態(tài)內(nèi)部類。

12.同步器的設(shè)計是基于模板方法模式的,即使用者需要繼承同步器并重寫指定的方法,隨后將同步器組合在自定義同組組件的實(shí)現(xiàn)中,并調(diào)用同步器提供的模板方法。

13.同步器可重寫的方法:

protected boolean tryAcquire(int arg)——獨(dú)占式獲取同步狀態(tài),實(shí)現(xiàn)該方法需要查詢當(dāng)前狀態(tài)并判斷同步狀態(tài)是否復(fù)合預(yù)期,然后再進(jìn)行CAS設(shè)置同步狀態(tài)。

protected boolean tryRelease(int arg)——獨(dú)占式釋放同步狀態(tài),等待獲取同步狀態(tài)的線程將有機(jī)會獲取同步狀態(tài)。

protected int tryAcquireShared(int arg)——共享式獲取同步狀態(tài),返回大于等于0的值,表示獲取成功,反之,獲取失敗。

protected boolean tryReleaseShared(int arg)——共享式釋放同步狀態(tài)

protected boolean isHeldExecusively()——當(dāng)前同步器是否在獨(dú)占模式下被線程占用,一般該方法表示是否被當(dāng)前線程所獨(dú)占。

14.隊列同步器的實(shí)現(xiàn)分析

1)同步隊列——

?同步隊列中的節(jié)點(diǎn)(Node)用來保存獲取同步狀態(tài)失敗的線程引用、等待狀態(tài)以及前驅(qū)和后繼節(jié)點(diǎn)。

同步器包含了兩個節(jié)點(diǎn)類型的引用,一個指向頭節(jié)點(diǎn),而另一個指向尾節(jié)點(diǎn)。為了保證未能成功獲取同步狀態(tài)的線程加入同步隊列過程的線程安全性,同步器提供了一個基于CAS的設(shè)置尾節(jié)點(diǎn)的方法:compareAndSetTail(Node expect, Node update),它需要傳遞當(dāng)前線程“認(rèn)為”的尾節(jié)點(diǎn)和當(dāng)前節(jié)點(diǎn),只有設(shè)置成功后,當(dāng)前節(jié)點(diǎn)才正式與之前的尾節(jié)點(diǎn)建立關(guān)聯(lián)。

節(jié)點(diǎn)進(jìn)入同步隊列之后,就進(jìn)入了一個自旋的過程,每個節(jié)點(diǎn)都在自省地觀察,當(dāng)滿足條件,獲取到了同步狀態(tài),就可以從這個自旋過程中退出。

2)獨(dú)占式同步狀態(tài)獲取與釋放

在獲取同步狀態(tài)時,同步器維護(hù)一個同步隊列,獲取狀態(tài)失敗的線程都會被加入到隊列中并在隊列中進(jìn)行自旋;移出隊列(或停止自旋)的條件是前驅(qū)節(jié)點(diǎn)為頭節(jié)點(diǎn)且成功獲取了同步狀態(tài)。在釋放同步狀態(tài)時,同步器調(diào)用tryRelease(int arg)方法釋放同步狀態(tài),然后喚醒頭節(jié)點(diǎn)的后繼節(jié)點(diǎn)。

3)共享式同步狀態(tài)獲取與釋放

共享式和獨(dú)占式獲取最主要的區(qū)別在于同一時刻能否有多個線程同時獲取到同步狀態(tài)。

轉(zhuǎn)載于:https://www.cnblogs.com/lvjygogo/p/8735171.html

總結(jié)

以上是生活随笔為你收集整理的多线程技术点二的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。