前言
synchronized修飾非靜態方法
synchronized修飾非靜態方法,實際上是對呼叫該方法的物件加鎖,俗稱「物件鎖」。
j**a中每個物件都有乙個鎖,並且是唯一的。假設分配的乙個物件空間,裡面有多個方法,相當於空間裡面有多個小房間,如果我們把所有的小房間都加鎖,因為這個物件只有一把鑰匙,因此同一時間只能有乙個人開啟乙個小房間,然後用完了還回去,再由jvm 去分配下乙個獲得鑰匙的人。
情況1:同乙個物件在兩個執行緒中分別訪問該物件的兩個同步方法
結果:會產生互斥。
解釋:因為鎖針對的是物件,當物件呼叫乙個synchronized方法時,其他同步方法需要等待其執行結束並釋放鎖後才能執行。正如上面所解釋的,相當於乙個物件只有一把鑰匙了,裡面的兩個同步方法是兩個房間,因此,同一時間只能用乙個鑰匙訪問乙個方法。
情況2:不同物件在兩個執行緒中呼叫同乙個同步方法
結果:不會產生互斥。
解釋:因為是兩個物件,就相當於兩個大房子,彼此之間互不干擾,具有兩把鑰匙。鎖針對的是物件,並不是方法,所以可以併發執行,不會互斥。形象的來說就是因為我們每個執行緒程式設計客棧在呼叫方法的時候都是new 乙個物件,那麼就會出現兩個空間,兩把鑰匙。
synchronized修飾靜態方法
synchronized修飾靜態方法,實際上是對該類物件加鎖,俗稱「類鎖」。
情況1:用類直接在兩個執行緒中呼叫兩個不同的同步方法
結果:會產生互斥。
解釋:因為對靜態物件加鎖實際上對類(.class)加鎖,類物件只有乙個,可以理解為任何時候都只有乙個空間,裡面有n個房間,一把鎖,因此房間(同步方法)之間一定是互斥的。
注:上述情況和用單例模式宣告乙個物件來呼叫非靜態方法的情況是一樣的,因為永遠就只有這乙個物件。所以訪問同步方法之間一定是互斥的。
情況2:用乙個類的靜態物件在兩個執行緒中呼叫靜態方法或非靜態方法
結果:會產生互斥。
解釋:因為是乙個物件呼叫,同上。都呼叫靜態方法的時候,相當於是同乙個類鎖,用的都是同乙個類物件。
都呼叫非靜態方法的時候,相當於是同乙個物件鎖。
情況3:乙個物件在兩個執行緒中分別呼叫乙個靜態同步方法和乙個非靜態同步方法
結果:不會產生互斥。
解釋:因為雖然是乙個物件呼叫,但是兩個方法的鎖型別不同,呼叫的靜態方法實際上是類物件在呼叫,即這兩個方法產生的並不是同乙個物件鎖,因此不會互斥,會併發執行。
例子pulbic class something()
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修飾靜態和非靜態方法
本文位址:
mongodb對於陣列基於位置的查詢和修改注意點
假設資料庫test中有乙個集合t,該集合中有乙個文件 mongodb中陣列下標從0開始。mongodb中陣列支援基於位置的修改,如果想將 array 對應的陣列的第乙個元素的值從 one 改為 three 可以這樣實現 db.t.update 但是,mongodb中的陣列不支援基於位置的查詢,如果想...
Python MIMEMultipart 修改資訊
今天呼叫同事的mail模組,由於預設讀取配置檔案來獲取to 收件人 資訊,不想改他 於是嘗試在外部賦值 message info to xx xx.com 注 message info mimemultipart alternative 發現收件人仍是之前配置檔案中的收件人,而不是我賦值的xx 查詢...
執行緒synchronized 例子
public class foo public int fix int y return x public class myrunnable implements runnable catch interruptedexception e system.out.println thread.curr...