synchronized用到不同地方對程式碼產生的影響:
1. synchronized關鍵字修飾方法
假設P1、P2是同一個類別的不同對象,這個類別中定義了以下幾種情況的同步區塊或同步方法,P1 、P2就都能夠調用他們。
public synchronized void method(){
//
}
這也就是同步方法,那麼這時synchronized鎖定的是呼叫這個同步方法物件。也就是說,當一個物件P1在不同的執行緒中執行這個同步方法時,他們之間會形成互斥,達到同步的效果。同時如果該物件中有多個同步方法,則當一個執行緒獲執行物件中的一個synchronized方法,則該物件中其它同步方法也不允許別的執行緒執行。但是這個物件所屬的Class所產生的另一物件P2卻能夠任意呼叫這個被加了synchronized關鍵字的方法。
上邊的範例程式碼等同於下列程式碼:
public void method() {
synchronized (this)
}
這次就是一個P1對象的對象鎖,哪個拿到了P1對象鎖的線程,才能夠呼叫P1的同步方法,而對P2而言,P1這個鎖和他毫不相干,程式也可能在這個情形下擺脫同步機制的控制,造成資料混亂。
2.同步區塊,範例程式碼如下:
public void method(SomeObject so) {
synchronized(so)
{
這時,鎖就是so這個對象,每個對象對應一個唯一的鎖,所以哪個執行緒拿到這個物件鎖誰就能夠運行他所控制的那段程式碼。當有一個明確的物件作為鎖時,就能夠這樣寫程式,但當沒有明確的物件作為鎖,只是想讓一段程式碼同步時,能夠創建一個特別的instance變數(他得是個物件)來充當鎖:
private byte[] lock = new byte[0];
Public void method(){
//
}
} 都經濟――查看編譯後的字節碼:產生零長度的byte[]物件只需3條操作碼,而Object lock = new Object()則需要7行操作碼。
Class Foo
{
public synchronized static void
}
public void method2()
{
/
}
}
這兩個同步方法都呼叫這個方法的物件所屬的類別的類別鎖定(Class,而不再是這個Class產生的某個特定物件了)。
能夠推斷:假如一個類別中定義了一個synchronized的static函數A,也定義了一個synchronized 的instance函數B,那麼這個類別的同一物件Obj在多執行緒中分別存取A和B兩個方法時,不會構成同步,因為他們的鎖都不相同。 A方法的鎖是Obj所屬的那個Class,而B的鎖是Obj所屬的這個物件。