Jdk1.5中包含了并發(fā)大神Doug Lea寫(xiě)的并發(fā)工具包java.util.concurrent,這個(gè)工具包中包含了顯示鎖和其他的實(shí)用同步組件。Doug Lea在構(gòu)建鎖和組件的時(shí)候,大多是以隊(duì)列同步器(AbstractQueuedSynchronizer)為基礎(chǔ)的,因此AbstractQueuedSynchronizer可以看作是并發(fā)包的基礎(chǔ)框架。因此掌握了AbstractQueuedSynchronizer的實(shí)現(xiàn)原理,也就掌握了大多數(shù)并發(fā)組件的實(shí)現(xiàn)原理。
AbstractQueuedSynchronizer使用一個(gè)int變量state表示同步狀態(tài),使用一個(gè)隱式的FIFO隊(duì)列(隱式隊(duì)列就是并沒(méi)有聲明這樣一個(gè)隊(duì)列,只是通過(guò)每個(gè)節(jié)點(diǎn)記錄它的上個(gè)節(jié)點(diǎn)和下個(gè)節(jié)點(diǎn)來(lái)從邏輯上產(chǎn)生一個(gè)隊(duì)列)來(lái)完成阻塞線程的排隊(duì)。
AQS是一個(gè)抽象類(lèi),當(dāng)我們要構(gòu)建一個(gè)同步組件的時(shí)候,需要定義一個(gè)子類(lèi)繼承AQS,這里應(yīng)用了模板方法設(shè)計(jì)模式,這里簡(jiǎn)單回顧一下模板模式:
模板模式由一個(gè)抽象類(lèi)和一個(gè)實(shí)現(xiàn)類(lèi)組成,抽象類(lèi)中主要有三類(lèi)方法: 模板方法:實(shí)現(xiàn)了算法主體框架,供外部調(diào)用。里面會(huì)調(diào)用原語(yǔ)操作和鉤子操作。 原語(yǔ)操作:即定義的抽象方法,子類(lèi)必須重寫(xiě)。 鉤子操作:和原語(yǔ)操作類(lèi)似,也是供子類(lèi)重寫(xiě)的,區(qū)別是鉤子操作子類(lèi)可以選擇重寫(xiě)也可以選擇不重寫(xiě),如果不重寫(xiě)則使用抽象類(lèi)默認(rèn)操作,通常是一個(gè)空操作或拋出異常。
在AQS中沒(méi)有原語(yǔ)操作,也就是說(shuō)自定義的子類(lèi)繼承AQS后,不會(huì)強(qiáng)制子類(lèi)重寫(xiě)任何方法。AQS只提供了若干鉤子操作,這些鉤子操作的默認(rèn)實(shí)現(xiàn)都是直接拋出異常。子類(lèi)不需要重寫(xiě)所有的鉤子操作,只需要根據(jù)要構(gòu)建的同步組件的類(lèi)型來(lái)決定要調(diào)用AQS中的哪些模板方法,再實(shí)現(xiàn)這些模板方法中用到了的鉤子操作即可。
AQS中可供子類(lèi)重寫(xiě)的鉤子操作有:
方法名稱 | 描述 |
boolean tryAcquire(int arg) | 獨(dú)占式獲取同步狀態(tài),成功返回true,失敗返回false。 |
boolean tryRelease(int arg) | 獨(dú)占式釋放同步狀態(tài),成功返回true,失敗返回false。 |
延伸閱讀
我想了解如何學(xué)習(xí) |