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);
}
}

volatile 的一个经典例子的更多相关文章

  1. 转:一个经典例子让你彻彻底底理解java回调机制

    一个经典例子让你彻彻底底理解java回调机制 转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273 ...

  2. 一个经典例子让你彻彻底底理解java回调机制

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273),请尊重他人的辛勤劳动成果,谢谢 所谓回调: ...

  3. 回调--一个经典例子让你彻彻底底理解java回调机制

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273),请尊重他人的辛勤劳动成果,谢谢 以前不理解什么叫回调 ...

  4. Java内存模型一个经典例子-指令重排序与CPU指令多发射导致执行结果异常

    先上代码: import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; ...

  5. MVVM模式的一个小例子

    使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...

  6. python之路第五篇之递归(进阶篇:续:经典例子剖析)

    递归 在函数内部,可以调用其他函数; 如果一个函数在内部调用自身本身,这个函数就是递归函数. 例如,我们来计算阶乘: n! = 1 x 2 x 3 x ... x n, 用函数f1(n)表示,可以看出 ...

  7. linux Posix 信号量 三 (经典例子)

    本文将阐述一下信号量的作用及经典例子,当中包括“<越狱>寄信”,“家庭吃水果”,“五子棋”,“接力赛跑”,“读者写者”,“四方恋爱”等 首先,讲 semWait操作(P操作)和semSig ...

  8. sql优化经典例子

    场景 我用的数据库是mysql5.6,下面简单的介绍下场景 课程表 create table Course( c_id int PRIMARY KEY, name varchar(10) ) 数据10 ...

  9. 【C语言学习笔记】空间换时间,查表法的经典例子!知识就是这么学到的~

    我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移植性那些角度. 在我们嵌入式中,我们需要根据实际资源的情况来设计我们的代码.比如当我们能用 ...

随机推荐

  1. python基础6--目录结构

    为什么要设计好目录结构? "设计项目目录结构",就和"代码编码风格"一样,属于个人风格问题.对于这种风格上的规范,一直都存在两种态度: 一类同学认为,这种个人风 ...

  2. Covariance 协方差分析

    sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...

  3. input file 图片上传展示重新上传

    html <div> <label class="imgMark">说明:</label> <div class="erWeiM ...

  4. 解决HTML5标签兼容的办法搜集

    HTML5的语义化标签以及属性,可以让开发者非常方便地实现清晰的web页面布局,加上CSS3的效果渲染,快速建立丰富灵活的web页面显得非常简单. HTML5的新标签元素有: <header&g ...

  5. K-means的缺点(优化不仅仅是最小化误差)

    K-means的缺点(优化不仅仅是最小化误差) #转载时,请注明英文原作David Robinson,译者Ding Chao.# 我最近遇到一个交叉验证的问题,我认为这个给我提供了一个很好的机会去用“ ...

  6. React-music 全家桶项目

    React-Music 全家桶项目 一.简介 该项目是基于React全家桶开发的一个音乐播放器,技术栈采用:Webpack + React + React-redux + React-router + ...

  7. LintCode 156: Merge Interval

    LintCode 156: Merge Interval 题目描述 给出若干闭合区间,合并所有重叠的部分. 样例 给出的区间列表 => 合并后的区间列表: [ [ [1, 3], [1, 6], ...

  8. 【BZOJ4870】组合数问题(计数DP,快速幂)

    题意: 1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1 思路:From http://blog.csdn.net/qq_33229466/artic ...

  9. 当月第一天、最后一天、下月第一天,时间date

    时间记录,不是时间戳 $thismonth = date('m'); $thisyear = date('Y'); $startDay = $thisyear . '-' . $thismonth . ...

  10. html5手机Web单页应用实践--起点移动阅读

    一开始以hybrid形式做了一个android的小说阅读客户端,叫4G阅读.而后由于业务需求,要迅速实现纯手机html5 版的,所以就直接在原先客户端内内嵌的网页进行改版,快速实现以后在优化的过程中发 ...