volatile关键字线程安全有关问题
volatile关键字线程安全问题在印象中,volatile修改的变量是线程安全的,我一直这么认为,殊不知还有条件的:1
volatile关键字线程安全问题
在印象中,volatile修改的变量是线程安全的,我一直这么认为,殊不知还有条件的:
1. 运算结果并不依赖变量的当前值,或者能够确保只有单一线程修改变量的值.
2. 变量不需要与其他的状态变理共同参与不变约束。
public class VolatileTest{ public static volatile int race = 0; public static void increase(){ race++; }}
这个方法不是线程安全的,只需要进行多线程测试便知。
虽然race变量是线程安全,但是
race++
==>
getstatic //race
iconst_1
iadd
putstatic
return
当getstatic指令把race的值取到操作栈顶时,volatile 关键字保证了race的值在此时是正确的,但是在执行iconst_1,iadd这些指令的时候,其他线程可能已经把race的值加大了.而在操作栈顶的值变成了过期的数据,所以putstatic指令执行后就可能把较小的race值同步到内存中了.
添加锁来保证线程安全。如下:
public class VolatileTest {private static Lock lock = new ReentrantLock();public static volatile int race = 1;public static void increace(){lock.lock();race = race + 1;lock.unlock();}}
这样就是线程安全了,造成线程不安全的原因是它违返了"运算结果并不依赖变量的当前值,或者能够确保只有单一线程修改变量的值"。
多线程编程,保持原子性很重要,否则要自己来保证线程安全
此文引用自《深入JVM_多线程编程》