关于引用类型的Java volatile关键字的问题

时间:2011-06-04 14:28:40

标签: java class volatile

我理解Java中的volatile关键字可以对引用变量和除long和double之外的所有原语进行读/写操作。

我也知道复合语句,例如递增整数,var ++,不是原子的,不应该用来代替synchronized语句。

但这堂课怎么样?

public class Setter{

private int num = 0;

public int setNum(int numIn){
num = numIn;
return num;
}
}

现在假设您将Setter的实例声明为volatile。

public class Main {
     private volatile Setter s;

public static void main(String[] args){
     s = new Setter();
     s.setNum(5);
}
}

是否调用setNum方法的原子?如果多个线程一次调用它,每个都有不同的值,这个语句是否安全?

以正确的方式使用volatile类并在不安全的复合语句中使用它的示例是什么?

3 个答案:

答案 0 :(得分:3)

  

调用方法setNum是原子?

不,不是。只有s的读/写才是易失性的。

这可以与Listfinal进行比较。这不足以使列表不可变,只有列表引用本身。

答案 1 :(得分:1)

不,volatile的使用仅适用于引用s,而不适用于它引用的对象的字段。您不能(安全地)让多个线程调用s.setNum(n)

但是,您可以创建一个新的Setter对象,在其中存储一个数字,然后更改s以引用新对象而不是旧对象。

答案 2 :(得分:1)

对象的引用和该对象的内容是不同的东西。在您的情况下,对象的引用( 是您的Main类 的prat)是volatile,这意味着当您读/写引用时< em> volatile 规则将适用。您可以自由地使用另一个非易失性对象的引用,并且 volatile 规则不适用于它。