volatile的使用原则
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。
http://www.cnblogs.com/shijiaqi1066/p/4352802.html
volatile关键字
对于普通变量,在一个线程中更新变量值,则在其他线程中该变量的值并不会改变(存在时间差)。如果需要在其他线程中立即可见,需要使用 volatile 关键字。volatile 不能代替锁,一般认为volatile 比锁性能好(不绝对)。
例:两条线程,使用一个标志用于控制一条线程的循环,该标志由另一条线程进行操作。即一条读,一条写。若该标志没有被volatile修饰,则线程中循环永远无法结束。
public class TestMain { static volatile boolean flag = true; public static void main(String[] args) throws InterruptedException { new Thread(new Runnable() { @Override
public void run() {
while (flag) {}
System.out.println(Thread.currentThread().getName() + "线程停止,死循环被打开");
}
}).start(); new Thread(new Runnable() { @Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} flag = false;
System.out.println(Thread.currentThread().getName() + "修改flag为" + flag);
}
}).start(); Thread.sleep(Integer.MAX_VALUE);
}
}
例:(书上的例子)通过一个程序理解volatile。使用-server 的JVM 运行该程序,若没有使用volatile则程序中while永远无法停止。VolatileStopThread只会在自身线程内存中查看stop的值,永远不会更新。
public class VolatileStopThread extends Thread { private volatile boolean stop = false; public void stopMe() {
stop = true;
System.out.println("stop = " + stop);
} public void run() {
int i = 0;
while (!stop) {
i++;
}
System.out.println("Stop thread");
} public static void main(String args[]) throws InterruptedException {
VolatileStopThread t = new VolatileStopThread();
t.start();
Thread.sleep(1000);
t.stopMe();
Thread.sleep(1000);
} }
volatile的使用原则
理解volatile关键字是熟悉Java并发编程的必经之路。如果要彻底理解volatile,首先需要理解Java内存模型。
volatile是java提供的一个轻量级的同步机制,用来对被修饰的变量进行同步。
使用volatile修饰的变量会对多个线程可见,也就是说任何线程都可以看到被volatile修饰的变量的最终值。
volatile并不能替代synchronized,因为volatile只提供了可见性,并没有提供互斥性;在多线程并发修改某个变量值时,依然会出现并发问题。
所以volatile最适合用的场景是一个线程修改被volatile修饰的变量,其他多个线程获取这个变量的值。
当多个线程并发修改某个变量值时,必须使用synchronized来进行互斥同步。
关于volatile的性能
若一个变量用volatile修饰,那么对该变量的每次读写,CPU都需要从主内存读取,性能肯定受到一定影响。
也就是说:volatile变量远离了CPU Cache,所以没那么高效。
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。
http://www.cnblogs.com/shijiaqi1066/p/4352802.html
最新文章
- yii2中自定义验证规则rules
- MySQL安装及主从配置
- POJ2375 Cow Ski Area (强连通)(缩点)
- Android开发-API指南-<;permission-group>;
- Spark系列(六)Master注册机制和状态改变机制
- 记一次npapi插件无窗口(windowless )化下的妙巧思路然后解决问题的超爽体验过程
- 使用wireshark抓本机之间的包(转)
- Linux 添加Nginx 到 service 启动
- C++基础——C面向过程与C++面向对象编程01_圆面积求解
- 巧妙设置Texture Type,将ShadowMask内存占用变成之前的1/4
- WPF中关于对前台Xaml中Triggers的一些重要思考。
- c/c++的预处理定义 Stringizing Operator (#) Charizing Operator (#@) Token-Pasting Operator (##)
- AJAX异步实现简单的瀑布流
- PHP 生成Word文档
- nginx: [error] open() ";/usr/local/var/run/nginx.pid"; failed (2: No such file or directory)
- SQL Server基础优化
- 设置Linux SSH登录后的欢迎信息
- php socket 简单理解
- python codecs模块 ---处理数据写入文件时会有编码不统一的问题
- 两名技术人员,历经8小时Piranha Games成功集成Xsolla