关于我在java中读取volatile关键字的应用,我真的很困惑.
以下陈述是否正确?"在对同一字段的每次后续读取之前发生对易失性字段的写入"
理想情况下应该使用volatile关键字吗?
有什么区别:
class TestClass
{ private int x;
synchronized int get(){return x;}
synchronized void set(int x){this.x = x;}
}
Run Code Online (Sandbox Code Playgroud)和
class TestClass
{ private volatile int x;
int get(){return x;}
void set(int x){this.x = x;}
}
Run Code Online (Sandbox Code Playgroud)
Ker*_*ğan 60
volatile是一个字段修饰符,而synchronized则修改代码块和方法.因此,我们可以使用这两个关键字指定简单访问器的三种变体:
int i1;
int geti1() {return i1;}
volatile int i2;
int geti2() {return i2;}
int i3;
synchronized int geti3() {return i3;}
Run Code Online (Sandbox Code Playgroud)
geti1()访问i1当前线程中当前存储的值.线程可以有变量的本地副本,并且数据不必与其他线程中保存的数据相同.特别是,另一个线程可能已i1在其线程中更新,但当前线程中的值可能与此不同更新的价值.事实上,Java有一个"主"内存的概念,这是保存变量当前"正确"值的内存.线程可以拥有自己的变量数据副本,并且线程副本可以与"主"内存不同.所以,事实上,它有可能为"主"内存有一个价值1对i1,i13对i1,如果线程1和线程2具有各自的i1,但这些更新的价值尚未被传播到"主"内存或其他线程.
另一方面,geti2()有效地访问i2"主"存储器的值.不允许volatile变量具有与"main"内存中当前保存的值不同的变量的本地副本.实际上,声明为volatile的变量必须使其数据在所有线程之间同步,因此无论何时在任何线程中访问或更新变量,所有其他线程都会立即看到相同的值.通常,volatile变量比"plain"变量具有更高的访问和更新开销.通常,允许线程拥有自己的数据副本以提高效率.
volitile和synchronized之间有两个不同之处.
首先同步获取并释放监视器上的锁定,这些锁定一次只能强制一个线程执行代码块.这是同步的众所周知的方面.但同步也同步内存.事实上,synchronized将整个线程内存与"主"内存同步.所以执行执行geti3()以下操作:
因此,volatile只在线程内存和"主"内存之间同步一个变量的值,synchronized会同步线程内存和"主"内存之间所有变量的值,并锁定和释放监视器以启动.明确同步可能比volatile更具开销.
http://javaexp.blogspot.com/2007/12/difference-between-volatile-and.html
| 归档时间: |
|
| 查看次数: |
10754 次 |
| 最近记录: |