点击上方“Java面试题精选”,关注公众号
面试刷图,查缺补漏
>>号外:往期面试题,10篇为一个单位归置到本公众号菜单栏->面试题,有需要的欢迎翻阅
阶段汇总集合:001期~180期汇总,方便阅读(增加设计模式)
简介
本文将介绍7种同步方法的访问场景,我们来看看着七种情况下,多线程访问同步方法是否还是线程安全的。这些场景是多线程编程中经常遇到的,而且也是面试时高频被问到的问题,所以不管是理论还是实践,这些都是多线程场景必须要掌握的场景。
八种使用场景:
接下来,我们来通过代码实现,分别判断以下场景是不是线程安全的,以及原因是什么。
-
两个线程同时访问同一个对象的同步方法
-
两个线程同时访问两个对象的同步方法
-
两个线程同时访问(一个或两个)对象的静态同步方法
-
两个线程分别同时访问(一个或两个)对象的同步方法和非同步方法
-
两个线程访问同一个对象中的同步方法,同步方法又调用一个非同步方法
-
两个线程同时访问同一个对象的不同的同步方法
-
两个线程分别同时访问静态synchronized和非静态synchronized方法
-
同步方法抛出异常后,JVM会自动释放锁的情况
场景一:两个线程同时访问同一个对象的同步方法
分析:这种情况是经典的对象锁中的方法锁,两个线程争夺同一个对象锁,所以会相互等待,是线程安全的。
两个线程同时访问同一个对象的同步方法,是线程安全的。
我们在前文中已经讲过了,这里:【185期】面试官:你能说说 Synchronized实现对象锁的两种方式以及它的原理吗?
场景二:两个线程同时访问两个对象的同步方法
这种场景就是对象锁失效的场景,原因出在访问的是两个对象的同步方法,那么这两个线程分别持有的两个线程的锁,所以是互相不会受限的。加锁的目的是为了让多个线程竞争同一把锁,而这种情况多个线程之间不再竞争同一把锁,而是分别持有一把锁,所以我们的结论是:
两个线程同时访问两个对象的同步方法,是线程不安全的。
代码验证:
线程名:Thread-0,运行开始
线程名:Thread-0,抛出异常,释放锁
线程名:Thread-1,运行开始
Exception in thread "Thread-0" java.lang.RuntimeException
at com.study.synchronize.conditions.Condition7.method0(Condition7.java:34)
at com.study.synchronize.conditions.Condition7.run(Condition7.java:17)
at java.lang.Thread.run(Thread.java:748)
线程:Thread-1,运行结束
测试结束
结果分析:
可以看出线程还是串行执行的,说明是线程安全的。而且出现异常后,不会造成死锁现象,JVM会自动释放出现异常线程的锁对象,其他线程获取锁继续执行。
总结
本文总结了并用代码实现和验证了synchronized
各种使用场景,以及各种场景发生的原因和结论。我们分析的理论基础都是synchronized
关键字的锁对象究竟是谁?多个线程之间竞争的是否是同一把锁?根据这个条件来判断线程是否是安全的。所以,有了这些场景的分析锻炼后,我们在以后使用多线程编程时,也可以通过分析锁对象的方式,判断出线程是否是安全的,从而避免此类问题的出现。
本文涵盖了synchronized
关键字的最重要的各种使用场景,也是面试官常常会问到的高频问题,是一篇值得大家仔细阅读和亲自动手实践的文章,喜欢本文请点赞和收藏。
来源:blog.csdn.net/x541211190/article/details/106272922
与其在网上拼命找题? 不如马上关注我们~
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/7515.html