synchronized用法
synchronized修飾的對(duì)象有幾種:
修飾一個(gè)類:其作用的范圍是synchronized后面括號(hào)括起來(lái)的部分,作用的對(duì)象是這個(gè)類的所有對(duì)象;
修飾一個(gè)方法:被修飾的方法稱為同步方法,其作用的范圍是整個(gè)方法,作用的對(duì)象是調(diào)用這個(gè)方法的對(duì)象;
修飾一個(gè)靜態(tài)的方法:其作用的范圍是整個(gè)方法,作用的對(duì)象是這個(gè)類的所有對(duì)象;
修飾一個(gè)代碼塊:被修飾的代碼塊稱為同步語(yǔ)句塊,其作用范圍是大括號(hào){}括起來(lái)的代碼塊,作用的對(duì)象是調(diào)用這個(gè)代碼塊的對(duì)象;
修飾一個(gè)類
其作用的范圍是synchronized后面括號(hào)括起來(lái)的部分,作用的對(duì)象是這個(gè)類的所有對(duì)象,如下代碼:
class ClassName {
public void method() {
synchronized(ClassName.class) {
// todo
}
}
}
修飾一個(gè)方法
synchronized 修飾一個(gè)方法很簡(jiǎn)單,就是在方法的前面加synchronized,例如:
public synchronized void method()
{
// todo
}
另外,有幾點(diǎn)需要注意:
在定義接口方法時(shí)不能使用synchronized關(guān)鍵字。
構(gòu)造方法不能使用synchronized關(guān)鍵字,但可以使用synchronized代碼塊來(lái)進(jìn)行同步。
synchronized 關(guān)鍵字不能被繼承 。如果子類覆蓋了父類的 被 synchronized 關(guān)鍵字修飾的方法,那么子類的該方法只要沒(méi)有 synchronized 關(guān)鍵字,那么就默認(rèn)沒(méi)有同步,也就是說(shuō),不能繼承父類的 synchronized。
修飾靜態(tài)方法
我們知道 靜態(tài)方法是屬于類的而不屬于對(duì)象的 。同樣的, synchronized修飾的靜態(tài)方法鎖定的是這個(gè)類的所有對(duì)象 。如下:
public synchronized static void method() {
// todo
}
修飾代碼塊
當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。
當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。
尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。
第三個(gè)例子同樣適用其它同步代碼塊。也就是說(shuō),當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。
以上規(guī)則對(duì)其它對(duì)象鎖同樣適用.
ps
修飾靜態(tài)方法其實(shí)是類鎖,區(qū)別于對(duì)象鎖。
public ClassA {
public synchronized static void staticMethod() {
// todo
}
public synchronized void method() {
// todo
}
public void method2() {
synchronized(ClassA.class) {
// todo
}
}
}
ClassA obj = new ClassA();
也就是說(shuō)ClassA.staticMethod() 和 obj.method() 并不會(huì)存在互斥關(guān)系,但是會(huì)和obj.method2()存在互斥關(guān)系。
pps
在平時(shí)多線程的使用中,特別是關(guān)于自己定義一些東西的遍歷和添加的時(shí)候,最好保證在遍歷的時(shí)候不要添加,在輸出數(shù)據(jù)的同時(shí)不要添加數(shù)據(jù),因?yàn)槎嗑€程機(jī)智,你無(wú)法控制輸出輸入在同一個(gè)線程的話,最好使用鎖機(jī)制,來(lái)避免一些錯(cuò)誤的產(chǎn)生。