正确使用 volatile 的模式

news/2024/7/4 9:35:59

很多并发性专家事实上往往引导用户远离 volatile 变量,因为使用它们要比使用锁更加容易出错。然而,如果谨慎地遵循一些良好定义的模式,就能够在很多场合内安全地使用 volatile 变量。要始终牢记使用 volatile 的限制 —— 只有在状态真正独立于程序内其他内容时才能使用 volatile —— 这条规则能够避免将这些模式扩展到不安全的用例。 

模式 #1:状态标志

也许实现 volatile 变量的规范使用仅仅是使用一个布尔状态标志,用于指示发生了一个重要的一次性事件,例如完成初始化或请求停机。 

很多应用程序包含了一种控制结构,形式为 “在还没有准备好停止程序时再执行一些工作”,如清单 2 所示: 

清单 2. 将 volatile 变量作为状态标志使用

volatile boolean shutdownRequested;

...

public void shutdown() { shutdownRequested = true; }

public void doWork() { 
while (!shutdownRequested) { 
// do stuff
}
}

很可能会从循环外部调用 shutdown() 方法 —— 即在另一个线程中 —— 因此,需要执行某种同步来确保正确实现 shutdownRequested 变量的可见性。(可能会从 JMX 侦听程序、GUI 事件线程中的操作侦听程序、通过 RMI 、通过一个 Web 服务等调用)。然而,使用 synchronized 块编写循环要比使用清单 2 所示的 volatile 状态标志编写麻烦很多。由于 volatile 简化了编码,并且状态标志并不依赖于程序内任何其他状态,因此此处非常适合使用 volatile。 

这种类型的状态标记的一个公共特性是:通常只有一种状态转换;shutdownRequested 标志从 false 转换为 true,然后程序停止。这种模式可以扩展到来回转换的状态标志,但是只有在转换周期不被察觉的情况下才能扩展(从 false 到 true,再转换到 false)。此外,还需要某些原子状态转换机制,例如原子变量。


http://www.niftyadmin.cn/n/4235275.html

相关文章

(转)Java中synchronized关键字锁定的内容

synchronized关键字能锁定什么?通常我们锁定的是一个对象或者是一个代码块。其实synchronized还能锁定一些其他内容。 同步分为 同步方法 和 同步块 两种方式。 变量分为 实例变量(不带static的变量) 和 类变量(带static的变量)。 同步锁锁定的内容是什么? 无论你将…

(转)解决Quartz定时任务被触发两次的问题

摘要: 解决quartz定时任务被触发两次的问题 方法1、通过改TOMCAT的配置文件server.xml配置 方法2、先把quartz配置信息提取出来,单独存成一个文件,比如applicationContext-quartz.xml 然后修改web.xml,让web容器启动时,可以加载该…

(转) Spring的quartz定时器同一时刻重复执行二次的问题解决{经测试不可用}

最近用Spring的quartz定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此。打印出他们的hashcode,发现是不一样的,也就是说,在web容器启动的时候,重复启了两个quartz线程…

(转)oracle常用函数一:数字函数

1,abs(n) 返回n的绝对值 [plain] view plaincopy SQL> select abs(-1),abs(1) from dual; ABS(-1) ABS(1) ---------- ---------- 1 1 2,ceil(n) 返回大于等于n的最小整数 [plain] view plaincopy SQL> select cei…

(转)上传文件思路

一看就是用了AJAX_UPLOAD,点图的时候就上传了吧.如果是这样的接下来你会需要:创建临时目录AJAX_UPLOAD至临时目录FORM提交时将临时目录文件mv至正式目录写个定时任务清理临时目录临时目录有很多方法,量不多的话日期目录最简单.任务清理前一天的任务临时目录的文件其实可以异步删…

Databing()的使用

我们先来看一个简单的例子&#xff1a; <% Page Language"C#" %> <% Import Namespace"System.Data" %> <Script Language"C#" Runat"Server"> public void Page_Load(Object src,EventArgs e) { //首先建立一…

【转】动态树

动态树是一种“超级数据结构”&#xff0c;它能够维护一个由若干有根树组成的森林&#xff0c;在对数的时间复杂度内支持&#xff1a; 1.查询一个点的父亲 2.查询一个点所在的树的根 3.修改某个节点的权 4.向从某个节点到它所在的树的根的路径上的所有的节点的权增加一个数 5.查…