synchronized用於給方法或者塊加鎖用的,只有獲得該物件或者塊的鎖的物件才能夠執行裡面的**,否則將阻塞在那裡,等待該鎖被釋放,然後獲得該鎖繼續執行。比如下面模擬售票的**:
/**
* 模擬售車票
* * @author administrator**/
public class synchronizeddemo else catch (exception e) }}
}};thread t1 = new thread(runnable);
thread t2 = new thread(runnable);
t1.start();
t2.start();
}}
執行結果:
thread-0:還剩餘9張車票
thread-1:還剩餘8張車票
thread-1:還剩餘6張車票
thread-0:還剩餘6張車票
thread-0:還剩餘4張車票
thread-1:還剩餘4張車票
thread-1:還剩餘3張車票
thread-0:還剩餘3張車票
thread-1:還剩餘2張車票
thread-0:還剩餘1張車票
thread-0:還剩餘0張車票
假如當前count=8,當t1執行完標記1(**中紅色的標記)的時候count=7,恰巧該執行緒的時間片用完了。這時候t2開始執行,當t2執行完標記1的時候count=6,接著輸出count的值,會輸出還剩餘6張,此時t2的時間片用完後,t1開始接著標記1後面執行,輸出count的值,會輸出還剩餘6張,這才輸出了上述中的結果。
解決辦法:
如果加入了synchronized**塊的話即可解決上述問題,核心**如下
synchronized (this)
其中this表示的是要鎖住物件的位址。
執行結果:
thread-0:還剩餘9張車票
thread-1:還剩餘8張車票
thread-0:還剩餘7張車票
thread-1:還剩餘6張車票
thread-1:還剩餘5張車票
thread-0:還剩餘4張車票
thread-1:還剩餘3張車票
thread-0:還剩餘2張車票
thread-0:還剩餘1張車票
thread-1:還剩餘0張車票
這才是正確的結果,這是由於當t1要執行標記2(**中紅色已標明)的時候,首先會判斷該位址是否被鎖住,如果沒有被鎖住,就會執行coount--,而此時t1的時間片用完了,t2開始執行,當t2執行到標記2的時候,首先判斷該位址是否被鎖住,發現該位址已經被鎖住了,於是t2等待鎖的釋放,當t2的時間片用完時,t1開始繼續執行,此時接著上次執行的位置執行,輸出count的值,然後釋放鎖,此時當t1的時間片用完後,t2發現該位址的鎖被釋放了,於是t2拿到該鎖,然後進去執行。。。以此類推。將會正確輸出結果。
只有該this所指向的位址相同時synchronized**塊才會起到作用,比如,將count的型別改為integer,synchronized**塊傳入count的位址,核心**如下:
integer count = 10;
synchronized (count)
結果輸出:
thread-1:還剩餘8張車票
thread-0:還剩餘9張車票
thread-1:還剩餘6張車票
thread-0:還剩餘6張車票
thread-0:還剩餘5張車票
thread-1:還剩餘4張車票
thread-0:還剩餘2張車票
thread-1:還剩餘2張車票
thread-0:還剩餘1張車票
thread-1:還剩餘0張車票
結果解析:
假如現在count=4,t1將count的位址鎖住後,執行完標記3後count=3,假設此時t1時間片用完,而此時t2開始執行,t2首先判斷count的位址是否被鎖住,發現此時count的位址並沒有被鎖住,這是因為t1鎖住的是count=4的位址,而此時t2判斷的是count=3的位址是否被鎖住,而count=3的位址並沒有被鎖住,所以t2會執行**塊中的**,執行完標記3後count=2,然後輸出還剩餘2張車票,當t2的時間片用完後,t1開始繼續執行輸出還剩餘2張車票,所以出現上述的現象。就是因為count的位址是變化的,所以一般給synchronized傳入的引數是乙個不可變的位址,比如類的位元組碼
synchronized關鍵字解析
一 修飾方法 1.修飾普通方法 對呼叫此方法的物件加鎖 2.修飾static方法 對呼叫此方法的類的所有物件加鎖 3.不能修飾構造方法,但是可以在構造方法內部修飾 塊 二 修飾 塊 1.synchronized this 相當於修飾普通方法 2.synchronized a.class 相當於修飾s...
解讀synchronized關鍵字
size large 最近在寫多執行緒程式,網上收集總結了synchronized的用法,結果如下 size 1 synchronized關鍵字的作用域有二種 1 是某個物件例項內,synchronized amethod 可以防止多個執行緒同時訪問這個物件的synchronized方法 如果乙個物...
synchronized 關鍵字分析
synchronized是典型的可衝入鎖,jdk1.5之後做了較大的優化 如圖,synchronized可以用在方法上也可以使用在 塊中,其中方法是例項方法和靜態方法分別鎖的是該類的例項物件和該類的物件。而使用在 塊中也可以分為三種,具體的可以看上面的 這裡的需要注意的是 如果鎖的是類物件的話,儘管...