我理解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类并在不安全的复合语句中使用它的示例是什么?
答案 0 :(得分:3)
调用方法setNum是原子?
不,不是。只有s
的读/写才是易失性的。
这可以与List
为final
进行比较。这不足以使列表不可变,只有列表引用本身。
答案 1 :(得分:1)
不,volatile
的使用仅适用于引用s
,而不适用于它引用的对象的字段。您不能(安全地)让多个线程调用s.setNum(n)
。
但是,您可以创建一个新的Setter
对象,在其中存储一个数字,然后更改s
以引用新对象而不是旧对象。
答案 2 :(得分:1)
对象的引用和该对象的内容是不同的东西。在您的情况下,对象的引用( 是您的Main类 的prat)是volatile
,这意味着当您读/写引用时< em> volatile 规则将适用。您可以自由地使用另一个非易失性对象的引用,并且 volatile 规则不适用于它。