直奔主题,说到线程,最核心的东西就是线程安全,那么来看看线程安全是什么,在互联网上可以搜到很多线程安全的定义1)可以在多个线程中调用,并且在线程间不会出现错误的交互、
2)可以同时被多个线程调用,而调用者无需执行额外的动作、 等等。
它们听起来非常像:如果某个类可以在多个线程中安全地使用,那么它就是一个线程安全的类。对于这种说法,没有太多正义,但是也没有太多帮助。
给出更准确的线程安全定义:当多个线程访问某个类时,这个类始终能表现出正确的行为,那么称这个类就是线程安全的。
以上来自《java并发编程实战》。
接下来记录一些经典且有助于理解的概念和心得
1、无状态的对象一定是线程安全的,不可变的对象一定是线程安全的(final)。
2、多个分别是原子的操作合并为一个复合操作不一定是线程安全的,还是存在竞态条件。
比如:if(!vector.contains(element)){
vector.add(element)
}
虽然vector的两个方法都是线程安全的,但是如果这样使用还是会出现竞态条件,add和contains不是同时被同步,当判 断是否包含的时候,add操作可能正在执行中,这样就产生了重复数据。
3、加锁的含义不只是局限于互斥行为,还包括内存可见性,为了确保所有线程都能看到共享变量的最新值,所有执行读写操作的线程都必须在同一个锁上同步。
4、volatile是一种比sychronized关键字更轻量级的同步机制,经典用法是检查某个状态标记以判断是否推出循环。
注意:当且仅当满足一下所有条件时才能使用volatile
1)对变量的写入操作不依赖变量的当前值,或者你能确保只有一个线程更新变量的值
2)改变量不会与其他状态变量一起纳入不变性条件中
3)在访问变量是不需要加锁
4)非私有方法return 私有对象引用会发布对象,把引用保存到static对象中也会发布对象,发布内部实例类会发布this引用
5)ThreadLocal的应用场景–有待深入研究