并发编程 — 判断线程安全


并发编程系列文章:
      初解线程池:http://ray-yui.iteye.com/blog/2072463
      详解线程池:http://ray-yui.iteye.com/blog/2075311
      并发数据类型:http://ray-yui.iteye.com/blog/2080454
      并发数据结构:http://ray-yui.iteye.com/blog/2084202
      volatile:http://ray-yui.iteye.com/blog/2231474
      判断线程安全:http://ray-yui.iteye.com/blog/2232931
      实现线程安全:http://ray-yui.iteye.com/blog/2234688


      Java对线程的支持有如一把双刃剑,线程安全性可能是非常复杂的.在没有足够的同步情况下,多个线程中得操作执行顺序是不可预测的,甚至会发生奇怪的结果.而分辨所编写的代码/程序/类是否线程安全或代码运行结果是否一直正确,是每个多线程开发人员必须具备的能力.


      对于判断所编写的类是否线程安全,可以参考以下几个方面


1.该对象是否会被多个线程访问修改
      假如对象会被多个线程访问,例如各种的Context或Factory,如Hibernate中的SessionFactory.SessionFactory是Session的生产工厂,一般对单库应用全局只需要保持一个SessionFactory,但对其属性的修改则是可以多个线程进行修改,因此若然没有足够的加锁机制,SessionFactory是一个线程不安全的对象.


2.注意静态变量.
      请注意变量一词,由于静态变量是属于该类和该类下所有对象共享,可直接通过类名访问/修改,因此在多线程的环境下.可以断言所有对静态变量的修改都会发生线程安全问题.除非静态变量为并发容器,通过委托线程安全容器发布对象.


3.改变对象内部状态的方法调用.
      请回看第一点,当一个对象的属性会被多个线程修改时,需要进行同步操作.但并不代表不提供某属性的setter方法就可以万事安心.而真正需要关注的是,哪些内部方法的调用或对外公开的方法调用会导致对象内部属性(状态)的改变.


4.单例
      相信大家在学习编程的时候都知道懒加载单例存在线程安全问题.先检查后操作是多线程开发中一个经常大意忽略的问题.因为并行程序共享的变量无时无刻都有可能发生变化,这涉及到数据失效性的问题.而单例由于是全局唯一,所以单例对象会被所有线程所访问,而单例中的属性若然允许进行修改,则会引发线程安全问题.当对象在Spring管理下默认是Singleton,当我们在三层架构开发下.在DAO(Repository)或Service中声明全局变量并对其进行操作,同样会引发线程安全问题.


总结:
      不必要的同步会带来性能损耗,判断失误缺少同步系统将失去正确性.判断自己开发的类是否线程安全是每一个多线程开发人员的必修课.

猜你喜欢

转载自ray-yui.iteye.com/blog/2232931
今日推荐