您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了synchronized怎么修飾靜態和非靜態方法,內容簡而易懂,希望大家可以學習一下,學習完之后肯定會有收獲的,下面讓小編帶大家一起來看看吧。
前言
最近被問到了這個問題,第一次回答的也是很不好,在此參考網上答案進行整理記錄。供大家學習參考。
Synchronized修飾非靜態方法
Synchronized修飾非靜態方法,實際上是對調用該方法的對象加鎖,俗稱“對象鎖”。
Java中每個對象都有一個鎖,并且是唯一的。假設分配的一個對象空間,里面有多個方法,相當于空間里面有多個小房間,如果我們把所有的小房間都加鎖,因為這個對象只有一把鑰匙,因此同一時間只能有一個人打開一個小房間,然后用完了還回去,再由JVM 去分配下一個獲得鑰匙的人。
情況1:同一個對象在兩個線程中分別訪問該對象的兩個同步方法
結果:會產生互斥。
解釋:因為鎖針對的是對象,當對象調用一個synchronized方法時,其他同步方法需要等待其執行結束并釋放鎖后才能執行。正如上面所解釋的,相當于一個對象只有一把鑰匙了,里面的兩個同步方法是兩個房間,因此,同一時間只能用一個鑰匙訪問一個方法。
情況2:不同對象在兩個線程中調用同一個同步方法
結果:不會產生互斥。
解釋:因為是兩個對象,就相當于兩個大房子,彼此之間互不干擾,具有兩把鑰匙。鎖針對的是對象,并不是方法,所以可以并發執行,不會互斥。形象的來說就是因為我們每個線程在調用方法的時候都是new 一個對象,那么就會出現兩個空間,兩把鑰匙。
Synchronized修飾靜態方法
Synchronized修飾靜態方法,實際上是對該類對象加鎖,俗稱“類鎖”。
情況1:用類直接在兩個線程中調用兩個不同的同步方法
結果:會產生互斥。
解釋:因為對靜態對象加鎖實際上對類(.class)加鎖,類對象只有一個,可以理解為任何時候都只有一個空間,里面有N個房間,一把鎖,因此房間(同步方法)之間一定是互斥的。
注:上述情況和用單例模式聲明一個對象來調用非靜態方法的情況是一樣的,因為永遠就只有這一個對象。所以訪問同步方法之間一定是互斥的。
情況2:用一個類的靜態對象在兩個線程中調用靜態方法或非靜態方法
結果:會產生互斥。
解釋:因為是一個對象調用,同上。都調用靜態方法的時候,相當于是同一個類鎖,用的都是同一個類對象。
都調用非靜態方法的時候,相當于是同一個對象鎖。
情況3:一個對象在兩個線程中分別調用一個靜態同步方法和一個非靜態同步方法
結果:不會產生互斥。
解釋:因為雖然是一個對象調用,但是兩個方法的鎖類型不同,調用的靜態方法實際上是類對象在調用,即這兩個方法產生的并不是同一個對象鎖,因此不會互斥,會并發執行。
例子
pulbic class Something(){ public synchronized void isSyncA(){} public synchronized void isSyncB(){} public static synchronized void cSyncA(){} public static synchronized void cSyncB(){} }
那么,加入有Something類的兩個實例a與b,那么下列哪組方法可以被1個以上線程同時訪問呢?
a. x.isSyncA()與 x.isSyncB() b. x.isSyncA()與 y.isSyncA() c. x.cSyncA()與 y.cSyncB() d. x.isSyncA()與 Something.cSyncA()
這里,很清楚的可以判斷:
a,都是對同一個實例的synchronized域訪問,因此不能被同時訪問
b,是針對不同實例的,因此可以同時被訪問
c,因為是static synchronized,所以不同實例之間不會被限制
d,書上的答案是可以被同時訪問的,答案理由是synchronzied的是實例方法與synchronzied的類方法由于鎖定(lock)不同的原因。
以上就是關于synchronized怎么修飾靜態和非靜態方法的內容,如果你們有學習到知識或者技能,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。