「非執行緒安全」問題存在於「例項變數」中,如果是方法內部的私有變數,則不存在「非執行緒安全問題」,所以結果也就是「執行緒安全」的了。示例如下:
public class hasselfprivatenum else
system.out.println(username+"num="+num);
}catch(interruptedexception e)
}}
public class threada extends thread
@override
public void run()
}
public class threadb extends thread
@override
public void run()
}
public class run
}
輸出結果如下,可見,方法內部的變數不存在非執行緒安全的問題
如果多個執行緒共同訪問1個物件中的例項變數,則有可能出現「非執行緒安全」問題,例項**如下:
public class hasselfprivatenum else
system.out.println(username+"num="+num);
}catch(interruptedexception e)
}}
public class threada extends thread
@override
public void run()
}
public class threadb extends thread
@override
public void run()
}
public class run
}
輸出結果如下,我們發現,出現了例項變數取值混亂的情況。
如何解決這個問題呢?只需要在public void addi(stirng username)方法前面加關鍵字synchronized即可,更改後的**如下所示:
public class hasselfprivatenum else
system.out.println(username+"num="+num);
}catch(interruptedexception e)
}}
輸出結果如下,在兩個執行緒訪問同一物件的同步方法時一定是執行緒安全的。
}輸出結果如下所示,兩個執行緒分別訪問同乙個類的兩個不同例項的相同名稱的同步方法,效果卻是以非同步的方式執行的,本例子由於建立了2個業務物件,在系統中產生出2把鎖,所以執行結果是非同步的。
關鍵字synchronized取得的鎖都是物件鎖,而不是把一段**或方法當做鎖,所以在上面的例子中,哪個執行緒先執行帶synchronized關鍵字的方法,哪個執行緒就持有該方法所屬物件的鎖lock,其他的執行緒只能呈等待狀態,前提是多個執行緒訪問的是同乙個物件。
但如果多個執行緒訪問多個物件,則jvm會建立多個鎖,上面的例子就是建立了2個hasselfprivatenum類的物件,所以就會產生2把鎖。
}輸出結果如下,實現結論如下:
1):a執行緒先持有object物件的lock鎖,b執行緒可以以非同步的方式呼叫object物件中的非synchronized型別的方法。
2):a執行緒先持有object物件的lock鎖,b執行緒如果在這時呼叫object物件中的synchronized型別的方法則需等待,也就是同步。
在上一節中我們已經實現多個執行緒呼叫同乙個方法時,為了避免資料出現交叉的情況,使用synchronized關鍵字進行同步。雖然在賦值進行了同步,但在取值時有可能出現一些意想不到的意外,這種情況就是髒讀。發生髒讀的情況就是在讀取例項變時,此值已經被其他執行緒更改過了。解決方式也是通過synchronized關鍵字。
關鍵字synchronized擁有鎖重入的功能,也就是在使用synchronized時,當乙個執行緒得到乙個物件後,再次請求此物件鎖時時可以再次得到該物件的鎖的。這也證明在乙個synchronized方法/塊內部呼叫本類的其他synchronized方法/塊時,是永遠可以得到鎖的。
可重入鎖也支援在父子類繼承的環境中,即子類可以通過「可重入鎖」呼叫父類的同步方法的。
當乙個執行緒執行的**出現異常時,其所持有的鎖會自動釋放。
即同步不可以繼承
執行緒同步synchronized
synchronized只是保證在同乙個時刻,其他執行緒不能訪問鎖定的資源,但是其他方法或者是變數不能鎖定控制的 synchronized obj 上面語法格式中synchronized後括號裡的obj就是同步監視器,上面 的含義是 執行緒開始執行同步 塊之前,必須先獲得對同步監視器的鎖定。任何時刻...
synchronized同步方法
關鍵字synchronized 如果是在方法內的變數,則無所謂的的變數同步問題。因為在方法內部的變數都是私有的。synchronized如果是加在方法上面,則是對該物件的例項進行同步。如果有兩個執行緒同時對該方法進行操作,則會同步進行。對個例項多個執行緒,不存在同步的問題,那時jvm會生成多個鎖,應...
Synchronized同步方法
非執行緒安全 其實會在多個執行緒對同乙個物件中的例項變數進行併發訪問時發生,產生的後果就是 髒讀 也就是取到的資料其實是被更改過的。1 方法內的變數為執行緒安全的 方法內部的私有變數,則不存在 非執行緒安全 的問題,所得結果也就是 執行緒安全 的。2 例項變數非執行緒安全 如果多個執行緒共同訪問乙個...