线程安全:
多个线程同时访问一个对象,不考虑在运行时环境下这些线程的调度和交替执行,无需进行额外的同步操作,或者在调用端也无需进行任何其它的协调操作,对于这个对象的调用行为都能够返回正确的结果,那么这个对象就是线程安全的。
为什么会有线程安全的问题:
根源在于多个线程之间存在共享数据访问的前提。
线程安全等级:
①不可变
只要一个对象被正确的构建出来,它的状态就不能够发生改变的。若果共享数据是基本数据类型,直接在定义时使用final关键字修饰即可,如果是对象类型,那就需要保证对象的行为不会对其状态造成改变,最简单的方式就是把对象中带有状态的变量都声明为final,这样在构造函数结束之后,它就是不可变的。
②绝对线程安全
不管运行时环境如何,调用者都不需要进行额外的同步操作。
通常要实现绝对的线程安全所要付出的代价是比较大的。通常javaAPI所给出的线程安全的类其实都不是绝对的线程安全。比如说Vector,当一个线程在get Vector里面的值,另一个线程在 remove Vector里面的值,这样一来很有可能就是get到的值其实已经被remove掉,这样一来就会报错。因此还是需要添加额外的同步措施,保障Vector的线程安全。
③相对线程安全
相对线程安全就是我们通常意义上所认为的线程安全。即他需要保证对象单个的操作是线程安全的,我们在调用的时候是不需要进行任何的同步操作,但是在连续调用的时候,就可能需要在调用端进行额外的同步手段来保证调用的正确性。像Vector、HashTable等都是。
④线程兼容
线程兼容的对象不是线程安全的,但是在调用端使用额外的同步手段可以保证在多线程环境下对象的安全使用。我们平常所说的一个类不是线程安全的绝大多数时候说的就是线程兼容。
⑤线程对立
线程对立就是调用端无论是否采取了同步措施,都无法在多线程环境下并发使用的代码。