每個物件都有乙個與之關聯的內在鎖。按照慣例,乙個執行緒,需要獨佔和一致的乙個物件的字段,在進入這個物件前得需要這個物件的內在鎖,當處理完這些欄位後,需要釋放這些內在鎖。只有有乙個執行緒擁有乙個內在鎖,其他的執行緒就不能獲取這同樣的鎖。當其他試圖獲取這把鎖時將被阻塞。
在同步方法中的鎖
當執行緒呼叫同步方法時,它自動的為這個方法的物件獲取乙個內在鎖並在方法返回的時候釋放鎖。即使返回是由於乙個異常導致的,鎖釋放也會發生。
你可能想知道當乙個static 同步方法被呼叫的時候會發生什麼,因為乙個靜態方法是與乙個類關聯的,而不是乙個物件。在這種情況下,執行緒為與這個類關聯的類物件獲取內在鎖。然後進入被鎖控制的類的靜態字段,那與任何類的乙個例項的鎖是有明顯區別的。
同步語句
另一種方法建立synchronized**通過同步語句。不像同步方法,同步語句必須指定提供內在鎖的的物件:
public void addname(string name)
namelist.add(name);
} 在這個例子中,addname方法需要多lastname和namecount欄位有乙個同步變化,但也需要避免其他物件方法的同步呼叫。(從同步**中呼叫其他物件的方法會引發一些問題,這些會在活性這部分講述)。沒有同步塊,不得不將有乙個分開的,非同步的方法來呼叫namelist.add。
同步塊也對改進有細粒度的同步的併發有用。例如,類mslunch有兩個例項字段,從不一起使用。所有這些欄位的更新都是同步的。但是沒有理由阻止c1的更新從交錯排列的c2的更新--並這樣做通過建立非必要阻塞減少併發。代替同步方法或者與之使用與之相關的鎖,我們單獨的建立兩個物件來提供鎖。
public class mslunch
} public void inc2()
} }
使用這種極端保健的方式。你必須絕對確定受影響的字段的內在鎖是安全的。
可重入同步(reentrant synchronization)
回顧那個乙個執行緒不能獲取另乙個執行緒擁有的鎖。但是乙個執行緒可以獲取它已經擁有的鎖。可重入同步允許乙個執行緒多次獲取同樣的鎖成為可能。這描述了一種情形同步**直接或者間接呼叫乙個包含了同步**的方法,並且兩組**使用相同的鎖。沒有可重入同步,同步**將不得話費更多的措施來避免乙個執行緒呼叫自身來阻塞。
佇列和同步鎖備忘
在不同執行緒中傳遞物件,尤其是匿名內部類物件,比如在a執行緒中初始化匿名內部類,傳遞到b執行緒中,在b執行緒中呼叫,相當於b執行緒中呼叫這個匿名內部類對應的外部物件。不同執行緒呼叫,是主動呼叫這個匿名內部類對應的物件,可能造成併發問題,可以加鎖。佇列是乙個容器,也在不同執行緒中呼叫,但是因為主要作用...
鎖和同步的區別
用法上的不同 synchronized既可以加在方法上,也可以載入特定 塊上,而lock需要顯示地指定起始位置和終止位置。synchronized是託管給jvm執行的,lock的鎖定是通過 實現的,它有比synchronized更精確的執行緒語義。效能上的不同 lock介面的實現類reentrant...
執行緒的同步和鎖
為避免多執行緒對同乙個物件進行操作,對資料造成的破壞。public class tt extends thread override public void run public int takeit int x public static void main string args 非靜態方法同步...