加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 静态变量vs Volatile

发布时间:2020-12-15 01:02:52 所属栏目:Java 来源:网络整理
导读:我只是以线程的角度提问……可能已经多次回答但请帮助我理解这一点. 参考这里的帖子 Volatile Vs Static in java 询问一个静态变量值也将是所有线程的一个值,那么我们为什么要选择volatile呢?我找到了以下示例: public class VolatileExample { public sta
我只是以线程的角度提问……可能已经多次回答但请帮助我理解这一点.

参考这里的帖子
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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读