synchronized
關鍵字用於處理多線程的競爭條件,被synchronized
關鍵字修飾的對象synchronized(obj)
就至關於給obj
對象上了一把鎖,誰拿到了鎖誰就能夠執行synchronized
代碼塊下的代碼,這種方法更像是把鎖住的對象實例做爲一個信號量,經過這個信號量判斷當前線程有沒有資格執行代碼塊中的東西,除此以外鎖的做用範圍跟這個obj
對象沒什麼關係。bash
public Object obj; public void fun(){ obj.funA(); synchronized(obj){ obj.funB(); } } 複製代碼
根據上面結論,給obj
對象上了鎖只會影響synchronized
代碼塊中的內容,同一時間只有一個線程能夠執行代碼塊中的代碼,而obj.funA();
則不會受到任何的影響。markdown
上面的例子中發現了鎖的對象起的效果只是一個讓線程之間競爭令牌,實際開發中若是隨便找一個全局屬性做爲對象鎖的話也不太合適,但若是爲synchronized
專門搞一個對象來鎖更不划算,因此synchronized(this)
是一個很好的選擇。多線程
public Object obj; public void fun(){ obj.funA(); synchronized(this){ obj.funB(); } } 複製代碼
該方法與上節代碼等價。this
值得注意的是,上面無論是synchronized(obj)
仍是synchronized(this)
他們鎖的做用範圍都是當前對象的實例,無論有多少個線程,都是本身對象實例的鎖本身的對象用,其餘對象實例的事管不着。spa
上圖兩個線程(T1,T2)中分別有兩個對象實例(a1,a2),他們同時競爭synchronized(this)
的做用範圍是同一個對象實例。線程
可是還有一個鎖,它的做用範圍是整個類:synchronized(A.class)
。code
使用synchronized(A.class)
鎖後,當前類下的全部對象實例都須要同時競爭使用權。orm
在Java中靜態屬性和靜態方法都是屬於類的,而不是屬於對象實例的,因此給靜態屬性和靜態方法上鎖都屬於給類上鎖,同上節類鎖 同樣。對象