關於學習多線程視頻的小結

一、同步方法:
1.在方法上添加synchronize關鍵字,一個實例一次只有一個線程能夠訪問
2.不同實例的同步方法,即使在方法上加上synchronize關鍵字,線程也是各自執行各自的
3.在方法上加上static和synchronize關鍵字,則全局同步,不論多少個實例,線程都要依次執行

二、同步代碼塊:
1.在代碼塊添加synchronize關鍵字,一個實例一次只有一個線程能夠訪問
2.如果同步兩個代碼塊,共用一個鎖,線程就輪流一個一個執行,兩個鎖則會併發執行
3.同步代碼塊時,如果參數爲.class對象,則不論多少個實例也要依次進行

三、問題:
1.兩個線程訪問的一個實例的同步方法,依次執行
2.兩個線程訪問兩個實例的同步方法,併發執行
3.兩個線程訪問synchronized的靜態方法,依次執行
4.同一個實例多線程同時訪問同步和非同步,非同步不受到同步的影響,並行執行
5.同一個實例多線程同時訪問一個實例的不同同步方法,只能依次進行
6.兩個線程訪問一個實例的靜態同步方法(.class)與非靜態同步方法(對象本身),併發執行
7.線程訪問同步方法拋出異常後,將會釋放鎖
8.同步方法裏訪問不同步方法,這時候也是線程不安全的。
9.鎖對象不能爲空
10.synchronized作用域不宜過大
11.避免死鎖
12.多線程釋放鎖的時候,jvm如何選擇正在等待的鎖?與jvm有關
13.synchronized只能一個線程執行,效率低,有什麼辦法提高性能?減少同步代碼的範圍,使用其他如讀寫鎖之類的鎖
14.怎麼靈活的控制鎖的獲取與釋放?可以繼承lock接口自己實現

四、核心思想:
1.一個鎖只能被一個線程獲取,沒拿到鎖的線程都要等待
2.每個實例都有自己的鎖,不同的實例的不同鎖互不影響。此外,如果是被static修飾的方法和鎖對象爲.class的時候所有對象共用一把鎖。
3.無論方法是正常執行還是拋出異常,都會釋放鎖。

五、synchronized鎖的性質:
1.可重入(避免死鎖,提高封裝性)
可重入的三種情況:
1)同一個方法是可重入的
2)可重入不要求是同一個方法
3)可重入不要求是同一個類,如字父類
原理:
由jvm進行跟蹤對象被加鎖的次數,每次獲取鎖,計數器加1,每次釋放,計數器減1
2.不可中斷

六、lock鎖:
1.lock鎖有鎖住和釋放兩個功能,等價於synchronized關鍵字。但是如果鎖住不釋放,則下一個線程沒有辦法獲取鎖。

七、jvm是通過monditor進行加鎖和解鎖的
1.monditorenter的三種情況:
1)鎖的計數器爲0,這時候線程獲取鎖,計數器加1
2)可重入的情況,線程繼續訪問,計數器累加
3)鎖的計數器不爲0,這時候線程只能等待,發生阻塞的情況
2.monditorenter的兩種情況:
1)計數器減1,如果爲0,說明該線程已經釋放鎖了,並且其他被阻塞的線程會繼續嘗試獲取鎖
2)計數器減1,如果不爲0,說明該線程是可重入進來的,會繼續擁有鎖

八、synchronized的缺陷:
1.效率低(不如lock)
1) 鎖的釋放情況少(執行完,異常)
2) 獲取鎖不能設置超時
3) 不能中斷正在嘗試獲取鎖的線程
2.不夠靈活(不如讀寫鎖),加鎖和釋放的時機單一
3.不知道是否成功獲取鎖(不如lock)

九、注意點:
1.join是將選定的線程加入主線程進行運作,而主線程停止,等待選定的線程運行完才能運作。
2.stop的停止方法現在都不用了,使用stop導致直接終止,沒有任何終止信息
3.interrupt不能直接打斷線程運行,可設置循環參數isInterrupted,進行打斷,但是會跟sleep衝突,所以也不是合適的方法

十、可見性:
1.線程的所有對共享數據的操作應該在線程自己的工作空間內完成,並且不能直接讀取主內存。
2.線程之間不能直接交互,需要通過主內存進行交互
3.實現方式
1)synchronized(原子性-同步,可見性)
2)volatile
4.JMM規定,加鎖時,會將工作空間的共享數據清除,讀取主內存數據;線程解鎖前,必須將工作空間數據更新在主內存中。
5.synchronized工作順序:獲取鎖,清空工作空間數據,獲取主空間數據,工作空間操作數據,工作空間數據拷貝到主空間,釋放鎖
6.volatile工作順序:共享數據被訪問時,強迫從主空間數據重新獲取;而讀取的變量改變時,強迫將改變的值刷新到主空間,但是不能保證原子性,對於i++等多步操作無效。

十一、創建線程的兩個方法:
1.實現runnable接口,需要創建Thread實例來引用該實現類
2.繼承Thread,只要直接創建實例,比實現runnable接口少一步

十二、線程的分類
1.用戶線程:前臺可見的
2.守護線程:不可見的,用戶線程結束後也會跟着結束,setDaemon(true),必須在star錢調用,否則拋出異常。
如數據庫連接池的檢測線程,jvm啓動後的檢測線程,垃圾回收線程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章