我是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
}
}
我请求你们,请你们展示一个易变功能的小程序,所以在技术上我也很清楚
答案 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 确保所有线程都看到变量的一致值