volatite适用的场合

volatite的使用有几点需要注意。

一.对写入变量的写入操作不依赖当前值

如  num++,num=num*2

这是因为volatite它只有可见性,却不满足原子性。

num++可分解为 

1 取num

2 num +1 加法操作

3 num=num  赋值操作

因不满足原子性,例如num=1。当线程a 执行到2加法操作时。线程b执行到3赋值操作。由于是volatite所以立即写入内存。

此时num=2。切换到线程a 继续执行3赋值操作时,Num还是等于。


当然,对于boolean变量是满足的。一般来说,Boolean只对它进行赋值操作。只有一步操作。并且是volatite,所以一赋值完就写入内存。对其他线程可见。

二. 该变量没有包含在具有其他变量的不变式中

不满足:不变式low<up

这里面有两个VOLATILE变量,它包含了一个不变式就是LOW<UP( if (value > upper) 和   if (value < low) )

public class A {
   private volatile int low=0;

   private volatile int up=100;

   public int getLow() { return low; }
   public int getUp() { return up; }

   public void setLow(int value) {
       if (value > upper)
            system.out.print(".......");
       low = value;
   }

   public void setUp(int value) {
       if (value < low)
           system.out.print(".......");

       up = value;
   }
}

初始值是0和100,如果有两个线程同时操作set函数,一比如A线程操作setlow(4),B线程setup(3),最后结果是4和3。

原因当然还是因为原子操作的问题。

线程a执行setLow 并执行到 if (value > upper)   马上切换线程b执行setup 执行到 if (value < low)

这两个线程都进入了if判断语句内,错误就很显而易见了。

三.为什么用volatite

看了volatite那么多不适用的地方,有人肯定会想怎么不用synchronized。synchronized满足原子性,又满足可见性。正事因为synchronized满足原子性,你想想,你要把它的代码全部执行完,才能切换进程,当然会慢很多。

所以为了提高性能当然用volatite。毕竟多线程就是来提高性能的。

猜你喜欢

转载自blog.csdn.net/xu505928168/article/details/90137137