2004-10-25
第八章線程和鎖
這章描述的是非常底層的jvm運作的時候的概念上的部分模型,與前部分的編譯不屬于一個層次。
本章提到的變量概念是指類實例,類變量,和類數組。而參數和局部變量并不強行要求到這個變量概念之中。
8。1術語和框架
jvm中有主寄存器,當一個線程被啟動時,會創建自己的工作寄存器,當線程運行,會對主寄存器中的數據進行拷貝,存入自己的工作寄存器中。
主寄存器包含每個變量的主拷貝。
主寄存器也包含鎖,每個對象有個與其相關的鎖。線程可以競爭獲得一個鎖。
相關術語:
use,assign,load,store,lock,unlock為線程可以執行的動作。
read,write,lock,unlock為主存儲器子系統可以執行的動作。
use,assign是線程執行引擎與工作存儲之間的緊密耦合交互作用。
lock,unlock是線程執行引擎與主存儲之間的緊密耦合交互作用。
主存儲與工作存儲之間卻是松散耦合的。
分別對應的動作就是:load,store和lock,unlock
注意有三個實體在協同工作:主存儲器,工作存儲器,線程運行引擎
8。2執行順序和一致性。
1。同線程執行動作排序
2、主存儲執行的、對同一變量的動作排序
3、主存儲執行的、對同一鎖的動作排序
4、不允許一個動作跟在其自身后面。
第4點特殊說明:雖然看起來無關緊要,但必須顯式說明,以保證完整性。因為這種危險確實存在。
線程的動作和主存儲的動作間的約束:
1、每個lock和unlock動作必須由一些線程和主存儲共同執行。
2、每個load動作,唯一的與一個write動作配對,這樣write動作跟在store動作后。
8。3有關變量的規則
線程T對變量V的操作約束:
1、T執行過程中只有需要相應使用V時才調用use,或者assign動作。
2、T執行的assign動作必須插入到T對V的load或者store和后繼的由T執行的對V的store之間。(保證主存儲內值的正確,同時保證assign動作之前工作存儲內存在V)
3、在T對V執行use和store之前,必須執行assign或load操作(保證工作存儲器中有V,并且已經初始化)
4、在V創建后,每個T在use或store之前,必須執行assign或load操作。
對于第4點:volatile(易變)變量有更嚴格的約束
由主存儲器執行的read和right操作的約束:
1、T對V的load,必須先有對應的read
2、T對V的store,必須后繼對應的write
3、動作A,B是T對V的load或store動作,P,Q為對應的read或write,如果A優先于B,則P必須有些于Q
?
8.4Double和long變量的非原子處理
由于32位機器的效率問題,有些jvm實現對double和long這種64位值操作是非原子的,導致一些同步問題(如程序員總是需要顯式指定同步于對double和long上的操作),其實這只是一種軟件設計對硬件的妥協而已。
8。5有關鎖的規則
線程為T,鎖為L,T執行的關于L的操作約束如下:
1、T對L的lock操作,必須對于每個不是T的線程S,S對L的unlock操作數等于之前的S對L的lock操作數
2、T對L的unlock操作,必須要求先前T對L的unlock操作數,小于先前T對L的lock操作數(不解不擁有的鎖)
8。6有關鎖和變量交互作用的規則
線程T,鎖L,變量V,T執行的關于L和V的操作約束如下:
1、在t對V的assign和隨后的unlock之間,必須插入store操作。對應于該store的write操作必須先于unlock操作(保證L對于V的有效性)。
2、在lock和隨后執行的use或store之間,必須插入assign或load操作。
8。7有關volatile(易變)變量的規則
線程T,易變變量V和W
1、load和use操作必須成對出現,緊挨在一起,并且load操作在前
2、assign和store操作必須成對出現,緊挨在一起,并且assign操作在前
3、A、B為T對V的use或assign,F、G為對應的load或store,P、Q為對應的read或write,如果A先于B,則P必須優先于Q。
8。8先見存儲操作
如果變量沒有聲明為violate,則store操作可以提前于assign,store操作將將要賦給V的值替代V實際的值進行store操作,只要滿足:
1、如果發生store,必然發生assign。
2、重定位的store和assign間未插入鎖定操作。
3、重定位的store和assign間未插入對V的load
4、重定位的store和assign間未插入其他對V的store
5、store操作將assign操作要放到線程T的Z作為存儲器中的值傳到主存儲器。
8。9討論
8。10可能的交換
一個關于同步和鎖的小例子。
8。11范例:無序寫
另一個例子
8。12線程
線程由Thread和ThreadGroup類創建并管理。創建Thread對象就創建一個線程,而且是創建線程的唯一方式。當線程被創建時,它還不是活躍的,當其start方法被調用時,開始運行。
8。13鎖和同步
每個對象都有與其關聯的鎖。
當synchronized方法被調用時,它自動執行鎖定操作;如果該方法是實例方法,它鎖定同實例相關聯的鎖,如果方法是static的,它鎖定同Class對象相關聯的鎖
8。13等待集和通知
每個對象除了相關的鎖外,還有相關的等待集,即一組線程,首次創建的對象,等待集為空。
講述了wait,notify,notifyall幾個方法,wait方法往等待集中增加內容,而notify或notifyall方法從等待集中刪除內容。
但不能完全讀懂內容,可細研究。
第九章優化
本章描述jvm中Sun版本中實現的優化。
在此優化中,編譯的jvm代碼在運行期修改,利用運行期獲得的信息,做比源指令更少的工作,以獲得更好的性能。
9。1通過重寫動態鏈接
對重寫的指令,指令的每個實例在其第一次執行時被替換為_quick偽指令,該指令實例隨后執行的總是_quick變體。
其余是對_quick偽指令的描述,可用于查閱,因為這是Sun的jdk在運行的時候的真正指令狀態。
第十章 操作碼的操作碼助記符
這章主要是個附錄的功能,可供查閱。
×××××××××××××××××××××××××××××××××××
在延期了將近一個月了之后,終于算是看過了一遍這本書,雖然有很多沒有看的非常明白的地方,但是比我預期的效果要好了許多了,進一步的細致研究可以安排在后面。