您的位置:首頁>正文

Java多執行緒——使用synchronized鎖實現執行緒同步

為什麼要用執行緒同步

我們先來看下這段代碼的運行結果:

Java學習交流群:495273252

在多執行緒上篇博客已經介紹過了, JVM採用的是搶佔式調度模型, 當一個執行緒sleep的時候, 其它執行緒會搶佔CPU資源。 如果發生在資料庫中, 就是“髒讀”。 synchronized鎖就是用來解決這個問題的, 多執行緒的執行緒同步機制實際上是靠鎖的概念來控制的。

第一種方式:synchronized關鍵字修飾函數方法

Java學習交流群:495273252

第二種方式:synchronized關鍵字修飾代碼塊

Java學習交流群:495273252

多個物件多個鎖的情況

三個執行緒同時進行, 每個執行緒只列印一個字母, 交替列印ABCABC...

Java學習交流群:495273252

prev代表前一個物件, self代表自身。 執行緒先持有前一個物件的鎖和本次要列印的物件的鎖, 執行列印, 然後喚醒一個正在等待當前物件鎖的執行緒(剩下的那個執行緒), 並讓它拿到對象鎖。 prev.wait()方法讓本執行緒進入等候狀態, 讓本執行緒休眠, 執行緒自動釋放其佔有的物件鎖,

並等待notify。 如此迴圈反復列印8次ABC。

總結一下

當多個執行緒訪問同一物件的時候, 只能有一個執行緒取得物件的鎖, 多個物件需要多個物件的鎖。

哪個執行緒執行了帶synchronized關鍵字的方法, 哪個執行緒就持有該方法所屬物件的鎖, 其他的執行緒要訪問這個物件鎖內的內容, 都只能等待這個鎖被釋放後, 再去搶佔資源獲得對象的鎖。

synchronized修飾非static的方法時, 鎖的就是物件本身, 也就是this。

synchronized修飾static的方法時, 方法中無法使用this, 所以它鎖的不是this, 而是這個類。 所以, static synchronized方法也相當於全域鎖。

使用synchronized關鍵字, 應儘量縮小代碼塊的範圍, 最好能在代碼塊上加同步, 而不是在整個方法上加同步。 因為你鎖的範圍大的話, 時間又長, 別的執行緒就不會獲得相應的資源。

A執行緒持有物件的鎖,B執行緒可以以非同步方式調用物件中的非synchronized同步的方法。

學習Java的同學注意了!!!

學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入Java學習交流群495273252,我們一起學Java!

A執行緒持有物件的鎖,B執行緒可以以非同步方式調用物件中的非synchronized同步的方法。

學習Java的同學注意了!!!

學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入Java學習交流群495273252,我們一起學Java!

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示