在多線程開發(fā)中,我們經(jīng)车灰ǎ看到synchronized(this)瀑梗、synchronized(*.class)與synchronized(任意對象)這幾種類型同步方法烹笔。但是是否知道這幾種寫法有什么區(qū)別了?下面根據(jù)代碼來分析:
1抛丽、synchronized代碼塊間的同步性
運(yùn)行結(jié)果:
結(jié)論:
當(dāng)一個(gè)線程訪問ObjectService的一個(gè)synchronized (this)同步代碼塊時(shí)谤职,其它線程對同一個(gè)ObjectService中其它的synchronized (this)同步代碼塊的訪問將是堵塞,說明synchronized (this)使用的是同一個(gè)對象鎖亿鲜。
2允蜈、驗(yàn)證synchronized (this)代碼塊是鎖定當(dāng)前對象
package?com.zwz.thread.demo2;??
public?class?ObjectService?{ ?
public?void?objectMethodA(){??
System.out.println("run----objectMethodA");??
????}??
public?void?objectMethodB(){??
synchronized?(this)?{??
try?{??
for?(int?i?=?1;?i?<=?10;?i++)?{??
System.out.println("synchronized?thread?name:"+Thread.currentThread().getName()+"-->i="+i);??
Thread.sleep(1000);??
????????????????}??
}catch?(InterruptedException?e)?{??
????????????????????e.printStackTrace();??
????????????}??
????????}??
????}??
}??
package?com.zwz.thread.demo2; ?
public?class?ThreadA?extends?Thread?{??
private?ObjectService?objectService; ?
public?ThreadA(ObjectService?objectService)?{??
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
super.run();??
????????objectService.objectMethodA();??
????}??
}??
package?com.zwz.thread.demo2; ?
public?class?ThreadB?extends?Thread?{??
private?ObjectService?objectService;??
public?ThreadB(ObjectService?objectService)?{ ?
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
super.run();??
????????objectService.objectMethodB();??
????}??
}??
package?com.zwz.thread.demo2;??
public?class?MainTest?{ ?
public?static?void?main(String[]?args)?throws?InterruptedException?{??
ObjectService?service=new?ObjectService();??
ThreadB?b=new?ThreadB(service);??
????????b.start();??
Thread.sleep(2000);??
ThreadA?a=new?ThreadA(service);??
????????a.start();??
????}??
}??
運(yùn)行結(jié)果:
可以看到?jīng)]有同步鎖的objectMethodA方法異步執(zhí)行了,下面我們將objectMethodA()加上同步蒿柳。
package?com.zwz.thread.demo2;??
public?class?ObjectService?{ ?
public?synchronized?void?objectMethodA(){??
System.out.println("run----objectMethodA");??
????}??
public?void?objectMethodB(){??
synchronized?(this)?{??
try?{??
for?(int?i?=?1;?i?<=?10;?i++)?{??
System.out.println("synchronized?thread?name:"+Thread.currentThread().getName()+"-->i="+i);??
Thread.sleep(1000);??
????????????????}??
}catch?(InterruptedException?e)?{??
????????????????????e.printStackTrace();??
????????????}??
????????}??
????}??
}??
運(yùn)行結(jié)果:
結(jié)論:
上面三個(gè)小例子我們可以知道饶套,多個(gè)線程調(diào)用同一個(gè)對象中的不同名稱的synchronized同步方法或synchronized(this)同步代碼塊時(shí),是同步的垒探。
1妓蛮、synchronized同步方法
①對其它的synchronized同步方法或synchronized(this)同步代碼塊調(diào)用是堵塞狀態(tài);
②同一時(shí)間只有一個(gè)線程執(zhí)行synchronized同步方法中的代碼圾叼。
2蛤克、synchronized(this)同步代碼塊
①對其它的synchronized同步方法或synchronized(this)同步代碼塊調(diào)用是堵塞狀態(tài);
②同一時(shí)間只有一個(gè)線程執(zhí)行synchronized同步方法中的代碼夷蚊。
3构挤、將任意對象作為對象監(jiān)視器
package?com.zwz.thread.demo3; ?
public?class?ObjectService?{??
private?String?uname;??
private?String?pwd;??
String?lock=new?String();??
public?void?setUserNamePassWord(String?userName,String?passWord){??
try?{??
synchronized?(lock)?{??
System.out.println("thread?name="+Thread.currentThread().getName()??
+"?進(jìn)入代碼快:"+System.currentTimeMillis());??
????????????????uname=userName;??
Thread.sleep(3000);??
????????????????pwd=passWord;??
System.out.println("thread?name="+Thread.currentThread().getName()??
+"?進(jìn)入代碼快:"+System.currentTimeMillis()+"入?yún)name:"+uname+"入?yún)wd:"+pwd);??
????????????}??
}catch?(InterruptedException?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
}??
package?com.zwz.thread.demo3; ?
public?class?ThreadA?extends?Thread?{??
private?ObjectService?objectService; ?
public?ThreadA(ObjectService?objectService)?{??
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
objectService.setUserNamePassWord("a",?"aa");??
????}??
}??
package?com.zwz.thread.demo3; ?
public?class?ThreadB?extends?Thread?{??
private?ObjectService?objectService; ?
public?ThreadB(ObjectService?objectService)?{??
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
objectService.setUserNamePassWord("b",?"bb");??
????}??
}??
package?com.zwz.thread.demo3; ?
public?class?MainTest?{??
public?static?void?main(String[]?args)?{??
ObjectService?service=new?ObjectService();??
ThreadA?a=new?ThreadA(service);??
a.setName("A");??
????????a.start();??
ThreadB?b=new?ThreadB(service);??
b.setName("B");??
????????b.start();??
????}??
}??
運(yùn)行結(jié)果:
下面我把String lock=new String();放在方法中:
package?com.zwz.thread.demo3;??
public?class?ObjectService?{ ?
private?String?uname;??
private?String?pwd;??
public?void?setUserNamePassWord(String?userName,String?passWord){??
try?{??
String?lock=new?String();??
synchronized?(lock)?{??
System.out.println("thread?name="+Thread.currentThread().getName()??
+"?進(jìn)入代碼快:"+System.currentTimeMillis());??
????????????????uname=userName;??
Thread.sleep(3000);??
????????????????pwd=passWord;??
System.out.println("thread?name="+Thread.currentThread().getName()??
+"?進(jìn)入代碼快:"+System.currentTimeMillis()+"入?yún)name:"+uname+"入?yún)wd:"+pwd);??
????????????}??
}catch?(InterruptedException?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
運(yùn)行結(jié)果:
結(jié)論:
多個(gè)線程持有對象監(jiān)視器作為同一個(gè)對象的前提下,同一時(shí)間只有一個(gè)線程可以執(zhí)行synchronized(任意自定義對象)同步代碼快惕鼓。
4筋现、synchronized(任意自定義對象)與synchronized同步方法共用
package?com.zwz.thread.demo4;??
public?class?ObjectService?{ ?
private?String?lock=new?String();??
public?void?methodA(){??
try?{??
synchronized?(lock)?{??
System.out.println("a?begin");??
Thread.sleep(3000);??
System.out.println("a???end");??
????????????}??
}catch?(InterruptedException?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
public?synchronized?void?methodB(){??
System.out.println("b?begin");??
System.out.println("b???end");??
????}??
}??
package?com.zwz.thread.demo4;??
public?class?ThreadA?extends?Thread?{ ?
private?ObjectService?objectService; ?
public?ThreadA(ObjectService?objectService)?{??
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
????????objectService.methodA();??
????}??
package?com.zwz.thread.demo4;??
public?class?ThreadB?extends?Thread?{ ?
private?ObjectService?objectService; ?
public?ThreadB(ObjectService?objectService)?{??
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
????????objectService.methodB();??
????}??
}??
package?com.zwz.thread.demo4; ?
public?class?MainTest?{??
public?static?void?main(String[]?args)?{??
ObjectService?service=new?ObjectService();??
ThreadA?a=new?ThreadA(service);??
a.setName("A");??
????????a.start();??
ThreadB?b=new?ThreadB(service);??
b.setName("B");??
????????b.start();??
????} ?
}??
運(yùn)行結(jié)果:
結(jié)論:
上面methodA持有l(wèi)ock對象鎖,methodB持有ObjectService對象鎖呜笑,不是同一個(gè)夫否,所以使用synchronized(任意自定義對象)進(jìn)行同步操作,對象監(jiān)視器必須是同一個(gè)對象叫胁。如果不是同一個(gè)凰慈,運(yùn)行就是異步執(zhí)行了。
5驼鹅、靜態(tài)同步synchronized方法
package?com.zwz.thread.demo5; ?
public?class?ObjectService?{??
public?synchronized?static?void?methodA(){??
try?{??
System.out.println("static?methodA?begin?線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
Thread.sleep(3000);??
System.out.println("static?methodA?end???線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
}catch?(InterruptedException?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
public?synchronized?static?void?methodB(){??
System.out.println("static?methodB?begin?線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
System.out.println("static?methodB?end???線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
????}??
}??
package?com.zwz.thread.demo5;??
public?class?ThreadA?extends?Thread?{ ?
@Override ?
public?void?run()?{??
????????ObjectService.methodA();??
????}??
}??
package?com.zwz.thread.demo5; ?
public?class?ThreadB?extends?Thread?{??
@Override??
public?void?run()?{??
????????ObjectService.methodB();??
????}??
}??
package?com.zwz.thread.demo5; ?
public?class?MainTest?{??
public?static?void?main(String[]?args)?{??
ThreadA?a=new?ThreadA();??
a.setName("A");??
????????a.start();??
ThreadB?b=new?ThreadB();??
b.setName("B");??
????????b.start();??
????}??
}??
運(yùn)行結(jié)果:
結(jié)論:
synchronized應(yīng)用在static方法上微谓,那是對當(dāng)前對應(yīng)的*.Class進(jìn)行持鎖。
6输钩、synchronized(*.class)代碼塊
package?com.zwz.thread.demo6; ?
public?class?ObjectService?{??
public?void?methodA(){??
try?{??
synchronized?(ObjectService.class)?{??
System.out.println("methodA?begin?線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
Thread.sleep(3000);??
System.out.println("methodA?end???線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
????????????}??
}catch?(InterruptedException?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
public?void?methodB(){??
synchronized?(ObjectService.class)?{??
System.out.println("methodB?begin?線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
System.out.println("methodB?end???線程名稱:"+Thread.currentThread().getName()+"?times:"+System.currentTimeMillis());??
????????}??
????}??
}??
package?com.zwz.thread.demo6;??
public?class?ThreadA?extends?Thread?{ ?
private?ObjectService?objectService; ?
public?ThreadA(ObjectService?objectService)?{??
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
????????objectService.methodA();??
????}??
}??
package?com.zwz.thread.demo6; ?
public?class?ThreadB?extends?Thread?{??
private?ObjectService?objectService;??
public?ThreadB(ObjectService?objectService)?{ ?
super();??
this.objectService?=?objectService;??
????}??
@Override??
public?void?run()?{??
????????objectService.methodB();??
????}??
}??
package?com.zwz.thread.demo6; ?
public?class?MainTest?{??
public?static?void?main(String[]?args)?{??
ObjectService?service=new?ObjectService();??
ThreadA?a=new?ThreadA(service);??
a.setName("A");??
????????a.start();??
ThreadB?b=new?ThreadB(service);??
b.setName("B");??
????????b.start();??
????}??
}??
運(yùn)行結(jié)果:
結(jié)論:
同步synchronized(*.class)代碼塊的作用其實(shí)和synchronized static方法作用一樣豺型。Class鎖對類的所有對象實(shí)例起作用。