关于volatile变量用法

时间:2013-02-13 05:47:30

标签: java

我是volatile变量的新手,但我正在阅读文章,其中声明2)在某些情况下,可见性变量可用作在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  
    }  

}  

我请求你们,请你们展示一个易变功能的小程序,所以在技术上我也很清楚

1 个答案:

答案 0 :(得分: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++;
   }
}

在这个例子中,你可以看到read操作总是在瞬间给出正确的计数器值,不过是原子操作(比如评估一个条件并做一些事情,并根据读取值进行读写)不保证线程安全。

您可以参考this答案了解更多详情。

  

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

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

来自JLS

  

字段可以声明为volatile,在这种情况下是Java Memory Model   确保所有线程都看到变量的一致值