synchronized 與 static synchronized 區(qū)別 以及synchronized塊
Posted on 2012-12-01 21:27 云云 閱讀(2625) 評(píng)論(0) 編輯 收藏1.synchronized與static synchronized 的區(qū)別
synchronized是對(duì)類的當(dāng)前實(shí)例進(jìn)行加鎖,防止其他線程同時(shí)訪問該類的該實(shí)例的所有synchronized塊,注意這里是“類的當(dāng)前實(shí)例”, 類的兩個(gè)不同實(shí)例就沒有這種約束了。那么static synchronized恰好就是要控制類的所有實(shí)例的訪問了,static synchronized是限制線程同時(shí)訪問jvm中該類的所有實(shí)例同時(shí)訪問對(duì)應(yīng)的代碼快。實(shí)際上,在類中某方法或某代碼塊中有 synchronized,那么在生成一個(gè)該類實(shí)例后,改類也就有一個(gè)監(jiān)視快,放置線程并發(fā)訪問改實(shí)例synchronized保護(hù)快,而static synchronized則是所有該類的實(shí)例公用一個(gè)監(jiān)視快了,也也就是兩個(gè)的區(qū)別了,也就是synchronized相當(dāng)于 this.synchronized,而static synchronized相當(dāng)于Something.synchronized.
一個(gè)日本作者-結(jié)成浩的《java多線程設(shè)計(jì)模式》有這樣的一個(gè)列子:
pulbic class Something(){
publicsynchronizedvoid isSyncA(){}
publicsynchronizedvoid isSyncB(){}
publicstaticsynchronizedvoid cSyncA(){}
publicstaticsynchronizedvoid cSyncB(){}
}
那么,加入有Something類的兩個(gè)實(shí)例a與b,那么下列組方法何以被1個(gè)以上線程同時(shí)訪問呢
a. x.isSyncA()與x.isSyncB()
b. x.isSyncA()與y.isSyncA()
c. x.cSyncA()與y.cSyncB()
d. x.isSyncA()與Something.cSyncA()
這里,很清楚的可以判斷:
a,都是對(duì)同一個(gè)實(shí)例的synchronized域訪問,因此不能被同時(shí)訪問 b,是針對(duì)不同實(shí)例的,因此可以同時(shí)被訪問 c,因?yàn)槭莝tatic synchronized,所以不同實(shí)例之間仍然會(huì)被限制,相當(dāng)于Something.isSyncA()與 Something.isSyncB()了,因此不能被同時(shí)訪問。 那么,第d呢?,書上的 答案是可以被同時(shí)訪問的,答案理由是synchronzied的是實(shí)例方法與synchronzied的類方法由于鎖定(lock)不同的原因。 個(gè)人分析也就是synchronized 與static synchronized 相當(dāng)于兩幫派,各自管各自,相互之間就無約束了,可以被同時(shí)訪問。目前還不是分清楚java內(nèi)部設(shè)計(jì)synchronzied是怎么樣實(shí)現(xiàn)的。
結(jié)論:A: synchronized static是某個(gè)類的范圍,synchronized static cSync{}防止多個(gè)線程同時(shí)訪問這個(gè) 類中的synchronized static 方法。它可以對(duì)類的所有對(duì)象實(shí)例起作用。
B: synchronized 是某實(shí)例的范圍,synchronized isSync(){}防止多個(gè)線程同時(shí)訪問這個(gè)實(shí)例中的synchronized 方法。
2.synchronized方法與synchronized代碼快的區(qū)別
synchronized methods(){} 與synchronized(this){}之間沒有什么區(qū)別,只是synchronized methods(){} 便于閱讀理解,而synchronized(this){}可以更精確的控制沖突限制訪問區(qū)域,有時(shí)候表現(xiàn)更高效率。
3.synchronized關(guān)鍵字是不能繼承的
這個(gè)在《搞懂java中的synchronized關(guān)鍵字》一文中看到的,我想這一點(diǎn)也是很值得注意的,繼承時(shí)子類的覆蓋方法必須顯示定義成synchronized。(但是如果使用繼承開發(fā)環(huán)境的話,會(huì)默認(rèn)加上synchronized關(guān)鍵字)