0

我是 volatile 变量的新手,但我正在阅读文章,其中指出 2) 在某些情况下,Volatile 变量可以用作在 Java 中实现同步的另一种方法,比如 Visibility。使用 volatile 变量,它保证一旦写入操作完成,所有读取器线程都会看到 volatile 变量的更新值,如果没有 volatile 关键字,不同的读取器线程可能会看到不同的值。

我请求你们能不能给我展示一个小的java程序,所以从技术上讲,我也很清楚。

我的理解是......易失性意味着每个线程访问变量都将有自己的私有副本,与原始副本相同。但是如果线程要更改该私有副本,那么原始副本将不会得到反映。

public class Test1 {  
   volatile int i=0,j=0;  
   public void add1()  
           {  
            i++;  
            j++;  
      }  
   public void printing(){  
       System.out.println("i=="+i+ "j=="+j);  
   }  

    public static void main(String[] args) {  
        Test1 t1=new Test1();  
        Test1 t2=new Test1();  
        t1.add1();//for t1 ,i=1,j=1  
        t2.printing();//for t2 value of i and j is still,i=0,j=0  
        t1.printing();//prints the value of i and j for t1,i.e i=1,j=1  
        t2.add1();////for t2 value of i and j is changed to i=1;j=1  
        t2.printing();//prints the value of i and j for t2i=1;j=1  
    }  

}  

I request you guys could you please show a small program of volatile functionality, so technically also it is clear to me

4

1 回答 1

1

您已阅读的易失性变量保证了可见性,但不保证原子性——线程安全的另一个重要方面。我将尝试通过一个例子来解释

public class Counter {
   private volatile int counter;

   public int increment() {
       System.out.println("Counter:"+counter); // reading always gives the correct value
       return counter++; // atomicity isn't guaranteed, this will eventually lead to skew/error in the expected value of counter.
   }

   public int decrement() {
       System.out.println("Counter:"+counter);
       return counter++;
   }
}

在示例中,您可以看到读取操作将始终在瞬间给出正确的计数器值,但是原子操作(例如评估条件并执行某些操作以及基于读取值进行读取和写入)线程安全性是不保证。

您可以参考答案以获取更多详细信息。

易失性意味着每个线程访问该变量都有自己的私有副本,与原始副本相同。但是如果线程要更改该私有副本,则原始副本将不会得到反映。

我不确定我是否正确理解您,但 volatile 字段意味着它们是从所有线程可访问的主内存读取和写入的 - 变量没有线程特定的副本(缓存)。

来自JLS

一个字段可能被声明为 volatile,在这种情况下,Java 内存模型确保所有线程看到该变量的一致值

于 2013-02-13T05:52:52.840 回答