1.修飾一個方法synchronized 修飾一個方法很簡單,就是在方法的前面加synchronized,例如: 在定義介面方法時不能使用synchronized關鍵字。 構造方法不能使用synchronized關鍵字,但可以使用synchronized代碼塊來進行同步。 synchronized ...
1.修飾一個方法
synchronized 修飾一個方法很簡單,就是在方法的前面加synchronized,例如:
public synchronized void method() { // todo }
在定義介面方法時不能使用synchronized關鍵字。
構造方法不能使用synchronized關鍵字,但可以使用synchronized代碼塊來進行同步。
synchronized 關鍵字不能被繼承 ,如果要同步需要顯式的加上關鍵字。
synchronized 關鍵字修飾的方法如果被重寫預設不同步,如果要同步需要顯式的加上關鍵字,或者super父類的方法也就相當於同步了。
2.修飾代碼塊
public void method() { synchronized(this) synchronized(XX.class) }
synchronized(this)鎖的是當前對象,當前有幾個對象那麼這個this就是有多份,這裡的this只能鎖同一個對象。
synchronized(XX.class)只要是這個類型的class這把鎖就都有用
當兩個併發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
以上規則對其它對象鎖同樣適用.
3.修飾靜態方法
我們知道 靜態方法是屬於類的而不屬於對象的 。同樣的, synchronized修飾的靜態方法鎖定的是這個類的所有對象,所有類用它都會有鎖的效果
public synchronized static void method() { // todo }
4.修飾一個類
其作用的範圍是synchronized後面括弧括起來的部分,作用的對象是這個類的所有對象,只要是這個類型的class不管有幾個對象都會起作用。如下代碼
class ClassName { public void method() { synchronized(ClassName.class) { // todo } } }
總結:
A. 無論synchronized關鍵字加在方法上還是對象上,如果它作用的對象是非靜態的,則它取得的鎖是對象;如果synchronized作用的對象是一個靜態方法或一個類,則它取得的鎖是對類,該類所有的對象同一把鎖。
B. 每個對象只有一個鎖(lock)與之相關聯,誰拿到這個鎖誰就可以運行它所控制的那段代碼。
C. 實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以儘量避免無謂的同步控制。
D.同步關鍵字鎖的是對象