Volatile Vs Static in java

问题:

static表示所有对象的值的一个副本是正确的,volatile表示所有线程的值的一个副本?
无论如何,static变量值也将是所有线程的一个值,那我们为什么要去volatile

回答:

在Java中声明一个静态的变量,意味着只有一个副本,无论创建了多少个类的对象。即使没有Objects创建,变量也可以访问。但是,线程可能具有本地缓存​​的值。
当变量为挥发物而不是静态的时,每个Object将有一个变量。所以表面上似乎与正常变量没有区别,但完全不同于静态的。然而,即使使用Object字段,线程也可能在本地缓存变量值。
这意味着如果两个线程同时更新同一个对象的变量,并且该变量未被声明为volatile,则可能存在其中一个线程在缓存中具有旧值的情况。
即使您通过多个线程访问静态的值,每个线程都可以具有本地缓存​​副本!为了避免这种情况,您可以将变量声明为静态挥发,这将强制线程在每次全局值时读取。
但是,挥发物不能替代正确的同步!
例如:

private static volatile int counter = 0;

private void concurrentMethodWrong() {
  counter = counter + 5;
  //do something
  counter = counter - 5;
}

同时多次执行concurrentMethodWrong可能导致计数器的最终值不等于零!
要解决这个问题,你必须实现一个锁:

private static final Object counterLock = new Object();

private static volatile int counter = 0;

private void concurrentMethodRight() {
  synchronized (counterLock) {
    counter = counter + 5;
  }
  //do something
  synchronized (counterLock) {
    counter = counter - 5;
  }
}

或使用AtomicInteger类。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Volatile Vs Static in java

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

+ 43 = 47