线程安全与线程不安全 线程安全( 二 )


简单类比
线程安全性问题跟外科医生做手术有点象,尽管手术的目的是改善患者的健康,但医生把手术过程分成了几个步骤,每个步骤如果不是完全结束的话,都会严重损害患者的健康 。
想想看,如果一个医生切开患者的胸腔后要休三周假会怎么样?然而单线程的程序中是不存在这种问题的,因为在一个线程更新某对象的时候不会有其他线程也去操作同一个对象 。
(除非其中有异常,异常是可能导致上述问题的 。当一个正在更新某对象的线程因异常而中断更新过程后,再去访问没有完全更新的对象,会出现同样的问题)
如何保证线程安全?1.
Confinement 限制数据共享 。将可变数据限制在单一线程内部,避免竞争 。核心思想就是线程之间不共享可变数据类型 。
2.
Immutable 将可变数据类型改为Immutable类型 。避免多线程间的race condition 。
3.
Threadsafe data type 共享线程安全的可变数据 。如果必须要在多线程间使用mutable的数据类型,必须要使用线程安全的数据类型 。在JDK的类文档中,记录着是否线程安全 。如List,Set,Map等集合类,都是线程不安全的 。
4.
Synchronization 通过锁的机制共享不安全的可变数据 。
线程安全的几种实现方式1,用final 修饰,不能修改的变量就是最安全的
2,用原子类或者线程安全的类,比如int的原子包装类的增长就是通过自旋和cas实现的,又比如concurrenthashmap
3,用阻塞的方式,比如同步块等
4,用非阻塞的方法,比如aqs实现,乐观锁等
【线程安全与线程不安全 线程安全】 5,采用线程封闭,localthread

秒懂生活扩展阅读