volatile 关键字的两层语义

一旦一个共享变量(类的成员变量、类的静态成员变量)被 volatile 修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序

方式一:变量不使用 volatile 修饰

public class VolatileTest extends Thread {
private static boolean flag = false; public void run() {
while (!flag) ;
} public static void main(String[] args) throws Exception {
new VolatileTest().start();
Thread.sleep(2000);
flag = true;
}
}

方式二:变量使用 volatile 修饰

public class VolatileTest extends Thread {
private static volatile boolean flag = false; public void run() {
while (!flag) ;
} public static void main(String[] args) throws Exception {
new VolatileTest().start();
Thread.sleep(2000);
flag = true;
}
}

运行结果

方式一:线程不会结束

方式二:线程会结束

public class TestMain {
public 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);
}
}

public class RunThread extends Thread {
/** volatile */
private volatile boolean isRunning = true; private void setRunning(boolean isRunning) {
this.isRunning = isRunning;
} public void run() {
System.out.println("进入 run() 方法中...");
while (isRunning == true) {
// doSomething()
}
System.out.println("线程结束了...");
} public static void main(String[] args) throws InterruptedException {
RunThread myThread = new RunThread();
myThread.start();
Thread.sleep(3000);
myThread.setRunning(false);
System.out.println("isRunning 的值已经设置为了 false");
Thread.sleep(1000);
System.out.println(myThread.isRunning);
}
}

public class RunThread extends Thread {
/** volatile */
private boolean isRunning = true; private void setRunning(boolean isRunning) {
this.isRunning = isRunning;
} public void run() {
System.out.println("进入 run() 方法中...");
while (isRunning == true) {
// doSomething()
}
System.out.println("线程结束了...");
} public static void main(String[] args) throws InterruptedException {
RunThread myThread = new RunThread();
myThread.start();
Thread.sleep(3000);
myThread.setRunning(false);
System.out.println("isRunning 的值已经设置为了 false");
Thread.sleep(1000);
System.out.println(myThread.isRunning);
}
}

最新文章

  1. 【Silverlight】打开Silverlight程序报错,"未找到导入的项目......请确认<Import>声明中的路径正确,且磁盘上存在该文件"
  2. mac下卸载MySQL
  3. Shader_2[杂]
  4. locale的设定及其LANG、LC_ALL、LANGUAGE环境变量的区别
  5. 20145209&20145309信息安全系统设计基础实验报告 (4)
  6. ubuntu14.04配置impala的odbc连接
  7. Jquery异步上传图片
  8. selenium学习记录
  9. JAVA字段的初始化规律
  10. CentOS7 安装 swoole
  11. SFTPTool 和 FTPTooL.java
  12. JS代码片段:一个日期离现在多久了
  13. 关于Windows 7的64位系统不兼容某些控件的问题
  14. Extjs load和reload的区别
  15. js select 实现左右传值.html
  16. 『openframeworks』shader制作三角形马赛克效果
  17. Entity Framework执行Sql语句返回DataTable
  18. PAT 团体程序设计天梯赛-练习集 L2-003. 月饼
  19. Tomcat使用Memcached Session Manager管理Session
  20. comm的用法

热门文章

  1. 用for语句从数组中剔除数据,注意,count,要放到for语句之外才行
  2. 前端PHP入门-013-变量作用域
  3. [吴恩达机器学习笔记]14降维5-7重建压缩表示/主成分数量选取/PCA应用误区
  4. JS零碎小知识
  5. MySQL免安装版配置部署
  6. SQL Server 2008过期导致MSSQLSERVER服务无法启动现象
  7. 51nod 1548 欧姆诺姆和糖果 (制约关系优化枚举)
  8. 给APP增加RSA签名
  9. 20155117 王震宇 2006-2007-2 《Java程序设计》第四周学习总结
  10. Java多线程学习(七)并发编程中一些问题