我只是以线程的角度提问……可能已经多次回答但请帮助我理解这一点.
参考这里的帖子
Volatile Vs Static in java
询问一个静态变量值也将是所有线程的一个值,那么我们为什么要选择volatile呢?我找到了以下示例:
public class VolatileExample { public static void main(String args[]) { new ExampleThread("Thread 1 ").start(); new ExampleThread("Thread 2 ").start(); } } class ExampleThread extends Thread { private static volatile int testValue = 1; public ExampleThread(String str){ super(str); } public void run() { for (int i = 0; i < 3; i++) { try { System.out.println(getName() + " : "+i); if (getName().compareTo("Thread 1 ") == 0) { testValue++; System.out.println( "Test Value T1: " + testValue); } if (getName().compareTo("Thread 2 ") == 0) { System.out.println( "Test Value T2: " + testValue); } Thread.sleep(1000); } catch (InterruptedException exception) { exception.printStackTrace(); } } } }
输出:
Thread 1 : 0 Test Value T1: 2 Thread 2 : 0 Test Value T2: 2 Thread 1 : 1 Test Value T1: 3 Thread 2 : 1 Test Value T2: 3 Thread 1 : 2 Test Value T1: 4 Thread 2 : 2 Test Value T2: 4
如果我从testValue中删除静态,结果是:
Thread 1 : 0 Test Value T1: 2 Thread 2 : 0 Test Value T2: 1 Thread 1 : 1 Test Value T1: 3 Thread 2 : 1 Test Value T2: 1 Thread 1 : 2 Test Value T1: 4 Thread 2 : 2 Test Value T2: 1
为什么线程2没有读取更新的值?如果它必须是静态的,那么使用volatile是什么?
有人可以链接到volatile的一个很好的例子,其中该变量未声明为静态.
谢谢
解决方法
问题在于它不是原子的.代码应该使用AtomicInteger.使用静态变量,两个线程都尝试更新相同的值,实际上是3个操作:get,1和store.这意味着两个线程之间存在竞争条件,并且它们相互覆盖.
Why thread 2 is not reading the updated value? If it has to be made static,whats the use of volatile?
静态和易变的做不同的事情. static使与该类关联的字段与对象实例相对应. volatile会强制任何字段的读取或写入穿过内存屏障.这允许多个线程读取和更新公共字段,但这不会保护您免受多个操作的影响.如果你使变量不是静态的,那么你就不需要volatile了,因为每个线程都会使用它自己的字段实例.
你应该使用AtomicInteger.这包装了一个volatile int,但也提供了增量操作的特殊处理:
private static AtomicInteger testValue = new AtomicInteger(1); ... testValue.incrementAndGet();
Can someone give link to a good example of volatile where that variable is not declare static.
当多个线程共享非静态字段时,您需要一个volatile.例如,如果您将testValue移动到VolatileExample类中,然后将VolatileExample类的相同实例传递到两个线程中,以便它们可以访问testValue.