《深入理解JAVA虚拟机》读书笔记12
第十三章 线程安全与锁优化
线程安全:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,
也不需要进行额外的同步,或者在调用方法进行任何其他的协调操作,调用这个对象的行为都可以获得
正确的结果,那这个对象就是线程安全的。
一、java语言中的线程安全
我们可以将JAVA语言中的各种操作共享的数据分为以下五类:不可变,绝对线程安全、相对线程安全
线程兼容和线程独立。
1、不可变
不可变的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要进行任何的
线程安全保障措施,至于一个对象被正确的构建出来,那其外部的可见状态永远也不会被改变。
永远也不会看到它在多个线程之中处于不一致的状态,“不可变”带来的安全性是最简单最纯粹的。
JAVA语言中,如果共享数据是一个基本数据类型,那么只有在定义时使用final关键字修饰它就可以
保证它是不可改变的。如果共享数据是一个对象,那就需要保证对象的行为状态不会对其状态产生任何
影响才是。
2、绝对线程安全
绝对的线程安全是指不管运行时环境如何,调用者都不需要任何额外的同步措施,这个往往需要付出很大的
代价,设置是不切实际的代价。即使是在JAVA API中标注的是线程安全的类也绝大多数不是线程安全的。
(这里的绝对线程安全笔者暂时也不是很理解,可以去深入理解Java 虚拟机中查看详细的解释)
3、相对线程安全
相对的线程安全就是我们通常意义上所讲的线程安全,它需要保证对这个单独的操作是线程安全的,我们在调用的时候
不需要在做额外的保障措施,但是对于一个特定顺序的调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性。
4、线程兼容
线程兼容是指对象本身并不是线程安全的,但是可以通过在调用端正确的使用同步手段来保证对象在并发环境中安全的使用
,我们平常说一个类不是线程安全的,绝大多数都是指这种情况。
5、线程对立
线程对立是指不论调用端是否采用了同步措施,都无法在多线程环境中并发使用代码。由于JAVA语言天生具有多线程的
特性,线程对立这种排斥多线程的代码是很少出现的,而且通常有害,应当比 避免。
一个线程对立的例子救赎Thread()类的suspend()和resume()方法。不过如今已经废弃。