Java面试之多线程安全(四)

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

此篇接上一篇Java面试之多线程状态(三)
   对于线程安全问题,想从是什么、为什么、怎么做三个方面来整理这篇知识点。
   首先,在《Java并发编程实战》书中,Brian Goetz大神是如许定义什么是线程安全性的。
   当多个线程访问某个类时,不管运行时情况接纳何种调理方式大概这些线程将怎样瓜代实行,而且在主调代码中不必要任何额外的同步或协同,这个类都能体现出正确的举动,那么就称这个类是线程安全的。
   简单来说,在多个线程访问某个方法大概对象的时候,不管通过任何的方式调用以及现场怎样去瓜代实行。在步调中不做任何同步干预操纵的情况下,这个方法大概对象的实行或修改都能按照预期的结果来反馈,那么这个类就是线程安全的。
   现实上,线程安全问题的具体体现体现在三个方面,原子性,可见性,有序性
   原子性,是指当一个线程实行一系列步调指令操纵的时候,它应该是不可停止的,因为一旦出现停止,站在多线程的视角来看,这一系列的步调指令会出现前后实行结果不同等的问题。
   这个和数据库内里的原子性是一样的,简单来说就是一段步调只能由一个线程完整的实行完成,而不能存在多个线程干扰。
   CPU的上下文切换,是导致原子性问题的核心,而JVM内里提供了synchronized关键字来办理原子性问题。
                       
                  CPU的上下文切换          可见性,就是说在多线程情况下,由于读和写是发生在不同的线程内里,有大概出现某个线程对共享变量的修改,对其他线程不是实时可见的。
   导致可见性问题的原因有很多,比如CPU的高速缓存、指令重排序,编译器的指令重排序。
   有序性,指的是步调编写的指令顺序和终极CPU运行的指令顺序大概出现不同等的征象。这种征象也可以称为指令重排序,
   以是有序性也会导致可见性问题。可见性和有序性可以通过JVM内里提供的一个volatile关键字来办理。
   线程安全问题只在多线程情况下才出现,单线程串行实行不存在此问题。包管高并发场景下的线程安全,可以从以下四个维度考量:
   1.数据单线程内可见。单线程总是安全的。通过限定数据仅在单线程内可见,可以避免数据被其他线程篡改。最典型的就是ThreadLocal线程局部变量,它存储在独立虚拟机栈的局部变量表中,与其他线程毫无瓜葛。
   2.只对对象。只读对象总是安全的。它的特性是允许复制、拒绝写入。最典型的只读对象有String、Integer等。一个对象想要拒绝任何写入,必须要满意以下条件:利用final关键字修饰,避免被继承;利用private final关键字避免属性被中途修改;没有任何更新方法;返回值不能为可变对象。
   3.线程安全类。某些线程安全类的内部有非常明确的线程安全机制。比如StringBuffer就是一个线程安全类,它接纳synchronized关键字来修饰相关方法。
   4.同步与锁机制。如果想要对某个对象进行并发更新操纵,但又不属于上述三类,必要自己在代码中实现安全的同步机制。固然这个机制支持的并发场景很有代价,但非常复杂且容易出现问题。
   注:此篇知识整理自《Java并发编程实战》、《咕泡》、《Java并发编程之美》
         ©    著作权归作者所有,转载或内容合作请联系作者     

喜欢的朋侪记得点赞、收藏、关注哦!!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户国营

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表