volatile

義往昔 1年前 ⋅ 1783 阅读

用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值, volatile很容易被误用,用来进行原子性操作。
当做原子操作的例子参考: http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
public volatile static int count = 0;
count ++ 不是原子操作, 用AtomicInteger 替代

volatile 详解: http://www.cnblogs.com/dolphin0520/p/3920373.html

Java中的原子操作包括:
1)除long和double之外的基本类型的赋值操作
2)所有引用reference的赋值操作
3)java.concurrent.Atomic.* 包中所有类的一切操作

    count++不是原子操作,是3个原子操作组合
    1.读取主存中的count值,赋值给一个局部成员变量tmp
    2.tmp+1
    3.将tmp赋值给count
    count++不是原子操作,是3个原子操作组合
    1.读取主存中的count值,赋值给一个局部成员变量tmp
    2.tmp+1
    3.将tmp赋值给count
    可能会出现线程1运行到第2步的时候,tmp值为1;这时CPU调度切换到线程2执行完毕,count值为1;切换到线程1,继续执行第3步,count被赋值为1------------结果就是两个线程执行完毕,count的值只加了1;        可能会出现线程1运行到第2步的时候,tmp值为1;这时CPU调度切换到线程2执行完毕,count值为1;切换到线程1,继续执行第3步,count被赋值为1------------结果就是两个线程执行完毕,count的值只加了1;

还有一点要注意,如果使用AtomicInteger.set(AtomicInteger.get() + 1),会和上述情况一样有并发问题,要使用AtomicInteger.getAndIncrement()才可以避免并发问题


全部评论: 0

    我有话说: