細論Synchronize的使用區別
Synchronize的作用
在并發編程中實作共享資料的同步,
Synchronize使用形式
Synchronize的使用方式大體分為兩種:Synchronize同步方法 以及 Synchronize塊,其本質都是對目標物件(或類)的鎖定,讓該方法變為原子操作,
Synchronize同步方法
Synchronize同步方法的使用上大致也分為兩種情況:修飾普通方法,與修飾靜態方法,
Synchronize修飾普通方法
先談談修飾普通方法,當我們給一個普通方法加上Synchronize修飾詞,此時,該方法即能實作同步,我們用不同的執行緒去跑這個方法時,同一時間,只能有一個執行緒進入該方法,保證了共享資源的安全性,
public synchronized void Something_A()
但是這里有幾個注意點:
- 在用多執行緒去跑該同步方法時,須注意改同步方法是否是來自于同一個實體物件,因為同步方法是屬于物件的,不同的物件的同步方法并不是同一個同步方法,也就意味著執行緒獲取的鎖,并不是同一把鎖,以至于執行緒并不能實作同步,
- 同一個類中如果有多個Synchronize修飾的方法,那么當一個執行緒獲取了一個方法的鎖后,其他執行緒并不能進入該類中任意Synchronize修飾的方法(除靜態方法),這也說明了Synchronize鎖的物件,在同步方法與靜態方法時不同的,(下面一段我會講到Synchronize修飾普通方法與修飾靜態方法的不同,)
Synchronize修飾靜態方法
public synchronized static void Something_B()
與Synchronize修飾普通方法一樣,修飾靜態方法也是讓多執行緒實作同步,當有執行緒獲取鎖后,其他執行緒便不能進入Synchronize修飾的靜態方法,
那么其與Synchronize修飾的普通方法有什么不同呢?其實很簡單,Synchronize修飾方法其實是對類或者物件加鎖,當Synchronize修飾普通方法時,是對當前物件(this)加鎖,而當其修飾靜態方法時,是對類進行加鎖,這一點很重要,也是對后面理解Synchronize塊有幫助的,
所以針對上文的注意點,Synchronize修飾靜態方法也有一些注意點:
- 因為其修飾的是靜態方法,而靜態方法是屬于類本身的,而無論實體化多少個物件,該類依舊只有一個,所以,如果執行緒跑的不是一個實體化物件的靜態同步方法,也會有同步的效果,因為Synchronize是對該類上鎖,
- 而為什么前文提到的某一執行緒獲取Synchronize修飾的普通方法后,其他依舊可以進入Synchronize修飾的靜態方法,原因不言而喻,前者獲取的是實體化物件的鎖,而后者獲取的是類的鎖,
對于Synchronize修飾同步方法,就先講到這里,
其實在在使用時,我們會出現一種情況,例如當一條執行緒進入Synchronize后,對其中的屬性A進行長時間的操作,而另一條執行緒在此期間想對屬性B進行短時間操作,但因為Synchronize修飾的原因,只能排隊等待,
這并不符合我們的邏輯,因為對于屬性A的更改與對屬性B的更改并不需要同步,但我們為了防止其他執行緒進入更改該執行緒的進入本方法,所以又不得不使用Synchronize,所以這種時候我們便可以使用Synchronize塊,
Synchronize塊
在了解了Synchronize修飾方法后,我們其實很容易再理解Synchronize塊的應用,其原理就是對我需要鎖定的物件或類上鎖,而這里我們也可以再細化出三種情況:
Synchronize修飾非this物件
此時Synchronize鎖定的便只是指定的該物件,例如上面所說的例子中,我們便可以使用如下方法提高同步的性能:
public void Something_A()
{
synchronized (A)
{
//此處為對A的操作,
}
}
public void Something_B()
{
synchronized (B)
{
//此處為對B的操作,
}
}
因為兩個Synchronize所鎖定的不是同一個物件,所以在某一執行緒進入Something_A()的Synchronize塊時,其他執行緒依舊可以進入Something_B()中的Synchronize塊,
Synchronize修飾this物件
該原理與Synchronize塊修飾普通方法相同,是對本物件的鎖定,故其性質也與之前的Synchronize修飾普通方法相同,
synchronized (this)
{
}
Synchronize修飾class
該原理與Synchronize塊修飾靜態方法相同,是對類的鎖定,故其性質也與之前的Synchronize修飾靜態方法相同,
synchronized (this.class)
{
}
//當然也可以延伸出下面的形式
synchronized (Object.class) // object為任意物件
{
}
總結
- Synchronize的作用是針對并發編程,實作同步,
- Synchronize的本質是對物件或類上鎖,而不是對于某一方法上鎖,
- 在判斷執行緒是否同步時,我們即可根據上文的方法觀察執行緒是否在爭搶同一把鎖,
- 在使用Synchronize時,我們應注意使用volatile關鍵字實作資料的同步,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/267068.html
標籤:java
上一篇:第一天
下一篇:Map與Set詳解
