1 简介

  synchronized在方法内,同步代码块,传入对象,使用的是对象锁,传入class对象,使用的是类锁

  作用于普通方法,也是对象锁,当前对象

  作用于静态方法,是类锁

2 同步方法示例

2.1两个synchronized 修饰的普通方法

public class SychTest1 {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){ //相当于synchromized(this)
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start();

      //等待200

try { Thread.sleep(200); } catch (InterruptedException e)

    </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendMsg();
}).start();
}

}

执行结果

EMAIL
MSG

2.2两个synchronized 修饰的普通方法,sendEmail睡了2秒

public class SychTest2 {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">2000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start(); </span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">200</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
</span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendMsg();
}).start();
}

}

执行结果,发现第一个线程调用的sendEmail方法虽然等待了2秒,还是先打印,因为它先获取了锁,第二个线程只能等待。它们竞争的是同一个锁对象p

EMAIL
MSG

2.3一个同步方法,一个普通方法

public class SychTest3 {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">2000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
</span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
} } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start(); </span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">200</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendMsg();
}).start();
}

}

执行结果

MSG
EMAIL

2.4两个同步方法,但是是两个不同的对象p和p2去调用同步方法

public class SychTest4 {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">2000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
} } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); Phone p2 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start(); </span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">200</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p2.sendMsg();
}).start();
}

}

执行结果,持有的是不同的锁对象p和p2

MSG
EMAIL

2.5两个静态同步方法

public class SychTest5 {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){ //相当于synchronized(Phone.class)
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">2000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
synchronized </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start(); </span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">200</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendMsg();
}).start();
}

}

执行结果,持有的是同一个类锁

EMAIL
MSG

2.6 两个静态同步方法,两个对象p和p2去调用

public class SychTest6 {//?
<span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">2000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
synchronized </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone();
Phone p2 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start(); </span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">200</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p2.sendMsg();
}).start();
}

}

执行结果,持有的是同一个类锁,和哪个对象去调用无关

EMAIL
MSG

2.7一个静态同步,一个非静态同步

public class SychTest7 {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">2000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start(); </span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">200</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendMsg();
}).start();
}

}

执行结果,一个持有类锁,一个持有对象锁

MSG
EMAIL

2.8一个静态同步方法,一个非静态同步方法,两个对象去调用

public class SychTest8 {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Phone{
synchronized </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> sendEmail(){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">2000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">EMAIL</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
synchronized </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sendMsg(){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">MSG</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { Phone p </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); Phone p2 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Phone(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p.sendEmail();
}).start(); </span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">200</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); } </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
p2.sendMsg();
}).start();
}

}

执行结果,一个持有类锁,一个持有对象锁

MSG
EMAIL

3 同步代码示例

3.1传入class对象

public class SychTest13 {
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> synchronized  <span style="color: #0000ff;">void</span><span style="color: #000000;"> aa()  {
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">aaa</span><span style="color: #800000;">"</span><span style="color: #000000;">);
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) throws InterruptedException { </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
synchronized (SychTest13.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">1000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">aaaaaaaaaaaa</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
}).start(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
synchronized (SychTest13.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">bbbbbbbbbb</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
}).start();
}

}

执行结果

aaaaaaaaaaaa
bbbbbbbbbbb

3.2传入同一个对象t1

public class SychTest14 {
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> synchronized  <span style="color: #0000ff;">void</span><span style="color: #000000;"> aa()  {
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">aaa</span><span style="color: #800000;">"</span><span style="color: #000000;">);
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) throws InterruptedException {
SychTest13 t1 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> SychTest13();
</span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
synchronized (t1){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">1000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">aaaaaaaaaaaa</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
}).start(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
synchronized (t1){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">bbbbbbbbbb</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
}).start();
}

}

执行结果

aaaaaaaaaaaa
bbbbbbbbbbb

3.3传入对象t1和t2

public class SychTest15 {
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> synchronized  <span style="color: #0000ff;">void</span><span style="color: #000000;"> aa()  {
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">aaa</span><span style="color: #800000;">"</span><span style="color: #000000;">);
} </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) throws InterruptedException {
SychTest13 t1 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> SychTest13();
SychTest13 t2 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> SychTest13();
</span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
synchronized (t1){
</span><span style="color: #0000ff;">try</span> { Thread.sleep(<span style="color: #800080;">1000</span>); } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) { e.printStackTrace(); }
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">aaaaaaaaaaaa</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
}).start(); </span><span style="color: #0000ff;">new</span> Thread(()-&gt;<span style="color: #000000;">{
synchronized (t2){
System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">bbbbbbbbbb</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
}).start();
}

}

执行结果

bbbbbbbbbb
aaaaaaaaaaaa

4 注意事项

4.1 异常

  锁会被释放,其它线程可能进来继续执行。
  会出现数据不一致的情况,多个servlet线程访问同一个资源时,如果第一个线程抛出异常,其他线程就会进入同步代码块,有可能会访问到异常产生时的数据(异常产生的数据很可能是不对的),出现数据不一致的情况

4.2 锁对象

  synchronized (obj),obj不要用String、常量、基本数据类型。
  因为使用字符串、常量,你可以使用,其它人也可以使用,你们很可能都不知道对方使用了,那么就有问题了

最新文章

  1. PHP项目实现手机端和PC端的页面切换
  2. 懵逼的闭包--for循环(转)
  3. Sublime Text 3插件安装
  4. [git]问题list
  5. 从0开始学angularjs-笔记01
  6. NGUI UIToggle
  7. “FAIL - Deployed application at context path but context failed to start”错误的解决
  8. 程序代码记Log
  9. 第一个Sprint冲刺第七天
  10. H264-AVS POC理解
  11. 【转】华为Java编程军规,每季度代码验收标准
  12. bzoj3669: [Noi2014]魔法森林 lct
  13. js事件防止冒泡
  14. a标签无跳转的死链接
  15. MySQL:MySQL的安装
  16. mysql日志分析工具之mysqlsla
  17. 第六章 使用 Bootstrap Typeahead 组件(百度下拉效果)(续)
  18. STA 141A, Homework
  19. ITP项目:一期版本分享
  20. Claims-based认证解析

热门文章

  1. AR Engine光照估计能力,让虚拟物体在现实世界更具真实感
  2. php自定义分页类
  3. 自学 TypeScript 第四天,手把手项目搭建
  4. 重新认识下JVM级别的本地缓存框架Guava Cache(2)——深入解读其容量限制与数据淘汰策略
  5. java中的自增运算
  6. java中加号的用法
  7. 或许是市面上最强的 Mock 工具
  8. pyCharm中下载包的速度慢的解决方案
  9. 模型驱动设计的构造块(下)——DDD
  10. LVGL 中图片使用问题