静态变量与挥发性 [英] Static variable vs Volatile

查看:77
本文介绍了静态变量与挥发性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是从线程角度询问...可能已经回答了很多次,但是请帮助我理解这一点.

I am only asking in threading perspective...probably answered many times but please help me to understand this.

参考在这里发表 Volatile Vs Static in Java

要求静态变量值也将成为所有线程的一个值,那么为什么我们要使用volatile?我发现以下示例:

asking a static variable value is also going to be one value for all threads, then why should we go for volatile? I found following example :

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中删除了静态变量,则会获得以下结果:

If I remove the static from the testValue, result obtained:

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不读取更新的值?如果必须将其设置为static,那么volatile的用途是什么?

Why thread 2 is not reading the updated value? If it has to be made static , whats the use of volatile?

有人可以链接到volatile的一个很好的例子吗,其中该变量不是声明为静态的.

Can someone give link to a good example of volatile where that variable is not declare static.

谢谢

推荐答案

问题是++不是原子的.该代码应改为使用AtomicInteger.使用static变量,两个线程都试图更新相同的值,而++实际上是3个操作:get,+ 1和store.这意味着两个线程之间存在竞争条件,它们正在相互覆盖.

The problem is that the ++ is not atomic. The code should use AtomicInteger instead. With the static variable, both threads are trying to update the same value and the ++ is actually 3 operations: get, +1, and store. This means that there is a race condition between both of the threads and they are overwriting each other.

为什么线程2不读取更新的值?如果必须将其设置为static,那么volatile的用途是什么?

Why thread 2 is not reading the updated value? If it has to be made static , whats the use of volatile?

staticvolatile做不同的事情. static使与类关联的字段与对象实例相对. volatile强制对字段的任何读取或写入越过内存屏障.这允许多个线程读取和更新公共字段,但这 not 不能保护您免受多种操作的影响.如果将变量 not 设为静态,则不需要volatile,因为每个线程都将使用其自己的字段实例.

static and volatile do different things. static makes the field associated with the class as opposed to the object instance. volatile forces any read or write of the field to cross a memory barrier. This allows multiple threads to read and update a common field but this does not protected you from multiple operations. If you make the variable not be static then you would not need the volatile since each thread would be working with it's own instance of the field.

您应该使用AtomicInteger.这包装了volatile int,还提供了增量操作的特殊处理:

You should use AtomicInteger. This wraps a volatile int but also provides special handling of increment operations:

private static AtomicInteger testValue = new AtomicInteger(1);
...
testValue.incrementAndGet();

有人可以链接到volatile的一个很好的例子吗,其中该变量不是声明为静态的.

Can someone give link to a good example of volatile where that variable is not declare static.

当多个线程共享一个非静态字段时,您将需要一个volatile.例如,如果将testValue上移到VolatileExample类中,然后将VolatileExample类的相同实例传递到两个线程中,以便它们可以访问testValue.

You would need a volatile on a non-static field when it was shared by multiple threads. For example, if you moved the testValue up into the VolatileExample class and then passed the same instance of the VolatileExample class into both threads so they could access testValue.

这篇关于静态变量与挥发性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆