你有没有在Java中使用volatile关键字?
在今天的工作中,我遇到了Java中的volatile
关键字。 不太熟悉它,我找到了这样的解释:
Java理论与实践:管理波动性
考虑到该文章解释关键字的详细信息,您是否曾经使用过该关键字,或者您是否曾经看到可以正确使用此关键字的情况?
volatile
具有内存可见volatile
语义。 基本上,写操作完成后, volatile
字段的值对所有读者(特别是其他线程)都可见。 没有volatile
,读者可以看到一些未更新的价值。
回答你的问题:是的,我使用volatile
变量来控制某些代码是否继续循环。 该循环测试volatile
值,如果为true
,则继续。 通过调用“停止”方法可以将条件设置为false
。 当循环停止方法完成执行后,循环会看到false
并终止测试。
本书强烈推荐的“Java Concurrency in Practice”一书给出了volatile
一个很好的解释。 本书是由编写问题中引用的IBM文章的同一人撰写的(实际上,他在该文章的底部引用了他的书)。 我对volatile
使用就是他的文章所称的“模式1状态标志”。
如果你想了解更多关于如何volatile
工作,请阅读Java内存模型。 如果你想超越这个水平,请查看像Hennessy&Patterson这样的好计算机体系结构书,并阅读关于缓存一致性和缓存一致性的内容。
“... volatile修饰符保证读取字段的任何线程都能看到最近写入的值。” - Josh Bloch
如果您正在考虑使用volatile
,请阅读处理原子行为的java.util.concurrent
包。
单身模式上的维基百科发布显示使用中不稳定。
关于volatile的重要一点:
synchronized
和volatile
。 synchronized
变量。 对变量使用synchronized
关键字是非法的,将导致编译错误。 可以使用java volatile
变量来代替在Java中使用synchronized
变量,该变量将指示JVM线程从主内存中读取volatile
变量的值,并且不会在本地缓存它。 资源
volatile的使用示例:
public class Singleton {
private static volatile Singleton _instance; // volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
在第一次请求来临时,我们正在懒惰地创建实例。
如果我们不将_instance
变量设置为volatile
那么创建Singleton
实例的Thread将无法与其他线程通信。 因此,如果线程A正在创建Singleton实例并且在创建之后,CPU就会破坏等等,所有其他线程将不能将_instance
的值看作非空值,并且他们会认为它仍然被赋值为空。
为什么会发生? 由于读线程线程没有进行任何锁定,并且在写线程从同步块出来之前,内存将不会同步,并且_instance
值不会在主内存中更新。 通过Java中的Volatile关键字,这由Java本身处理,所有读者线程都可以看到这些更新。
结论 : volatile
关键字也用于在线程之间传递内存内容。
不使用volatile的示例用法:
public class Singleton{
private static Singleton _instance; //without volatile variable
public static Singleton getInstance(){
if(_instance == null){
synchronized(Singleton.class){
if(_instance == null) _instance = new Singleton();
}
}
return _instance;
}
上面的代码不是线程安全的。 虽然它在同步块内再次检查实例的值(出于性能原因),但JIT编译器可以重新排列字节码,以便在构造函数完成其执行之前设置对实例的引用。 这意味着getInstance()方法返回一个可能尚未完全初始化的对象。 为了让代码是线程安全的,关键字volatile可以在Java 5以后用于实例变量。 标记为volatile的变量只有在对象的构造函数完成完成后才会被其他线程看到。
资源
java中的非易失性使用快速迭代器通常使用列表对象上的volatile
计数器来实现。
Iterator
,计数器的当前值被嵌入到Iterator
对象中。 Iterator
操作时,该方法会比较两个计数器值,如果它们不同则抛出ConcurrentModificationException
。 故障安全迭代器的实现通常是轻量级的。 它们通常依赖于特定列表实现的数据结构的属性。 没有一般的模式。
链接地址: http://www.djcxy.com/p/17415.html