volatile 的一个经典例子
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 的一个经典例子的更多相关文章
- 转:一个经典例子让你彻彻底底理解java回调机制
一个经典例子让你彻彻底底理解java回调机制 转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273 ...
- 一个经典例子让你彻彻底底理解java回调机制
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273),请尊重他人的辛勤劳动成果,谢谢 所谓回调: ...
- 回调--一个经典例子让你彻彻底底理解java回调机制
本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273),请尊重他人的辛勤劳动成果,谢谢 以前不理解什么叫回调 ...
- Java内存模型一个经典例子-指令重排序与CPU指令多发射导致执行结果异常
先上代码: import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; ...
- MVVM模式的一个小例子
使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...
- python之路第五篇之递归(进阶篇:续:经典例子剖析)
递归 在函数内部,可以调用其他函数; 如果一个函数在内部调用自身本身,这个函数就是递归函数. 例如,我们来计算阶乘: n! = 1 x 2 x 3 x ... x n, 用函数f1(n)表示,可以看出 ...
- linux Posix 信号量 三 (经典例子)
本文将阐述一下信号量的作用及经典例子,当中包括“<越狱>寄信”,“家庭吃水果”,“五子棋”,“接力赛跑”,“读者写者”,“四方恋爱”等 首先,讲 semWait操作(P操作)和semSig ...
- sql优化经典例子
场景 我用的数据库是mysql5.6,下面简单的介绍下场景 课程表 create table Course( c_id int PRIMARY KEY, name varchar(10) ) 数据10 ...
- 【C语言学习笔记】空间换时间,查表法的经典例子!知识就是这么学到的~
我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移植性那些角度. 在我们嵌入式中,我们需要根据实际资源的情况来设计我们的代码.比如当我们能用 ...
随机推荐
- TCP ------ 抓包分析(seq ack)
总结: 1.ACK包可以和其他包合在一起,比如ACK包可以携带数据 2.可以接收多个数据包后,一次性给一个应答,不用每个数据包一一对应给应答 3.在通信过程中,通过接收到的包的ack值可以判断是否是上 ...
- array_filter 过滤一维中空数组,数组的序列不变
<?php header('Content-type:text;charset=utf8'); $str = "%11111%22222%333333%"; $arr = e ...
- OpenCV---直方图反向投影
一:直方图反向投影的方法 二:二维直方图的表示 (一)直接显示 def hist2D_demo(image): hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV) hi ...
- js实现数组排序
1. JavaScript的sort()方法 var array = [1,4,-8,-3,6,12,9,8]; function compare(val1,val2){ return val1-va ...
- 【转】 虚拟机Linux不能上网简单有效的解决办法(NAT模式下)
前提条件: a. 确保VMware Network Adapter for VMnet8 处于启用状态,这个是NAT网络模式要用的虚拟网卡.注意这个网卡的IP地址,不需要做手动设置 b. 确保 VMw ...
- Spring bean - scope详解
Scope是定义Spring如何创建bean的实例的. 在创建bean的时候可以带上scope属性,scope有下面几种类型. Singleton 这也是Spring默认的scope,表示Spring ...
- 【BZOJ】1537: [POI2005]Aut- The Bus
[算法]DP+线段树求区间max(二维偏序) [题解] 状态转移方程:f[i]=max(f[j]+v[i]),x[j]<x[i]&&y[j]<y[i]. 观察j的条件限制显 ...
- JavaScript事件和方法
单击一个超链接触发事件 1.用a标签的onclick <a href="#" onclick="js代码"> 这种写法呢,存在一种弊端,就是点击后会 ...
- 绿色的宠物店cms后台管理系统模板——后台
链接:http://pan.baidu.com/s/1c7qmsA 密码:2es8
- spring-boot 更换依赖版本
创建Spring Boot操作步骤如下: 在File菜单里面选择 New > Project,然后选择Spring Initializr 更换版本 或 pom spring-boot-start ...