java线程学习之volatile关键字
volatile变量的主要作用:是使变量在多个线程间可见。
在java中每一个线程都会有一块工作内存区,其中存放着所有线程共享的主内存的变量值的拷贝。当线程执行时,它在自己的工作内存区操作这些变量,为了读取一个共享的变量,一个线程会获取锁定并去清除它的内存工作区,把这些共享变量从所有线程的共享工作区中正确的装入到它自己所在的工作内存区中,当线程解锁时保证该工作内存区中变量的值写回到共享内存中。
volatile的作用就是强制线程到主内存(共享内存)里读取数据,而不去工作线程区里去读取,从而实现了多个线程间变量可见。也就是满足了线程安全的可见性。
当然用synchronized也能实现volatile的功能,但是仅仅为了读写一个或两个实例域就是用synchronized,会让CPU开销很大。
举个栗子:
public class RunThread extends Thread{
private volatile boolean isRunning = true;
private void setRunning(boolean isRunning){
this.isRunning = isRunning;
}
public void run(){
System.out.println("进入run方法..");
int i = 0;
while(isRunning == true){
//..
}
System.out.println("线程停止");
}
public static void main(String[] args) throws InterruptedException {
RunThread rt = new RunThread();
rt.start();
Thread.sleep(1000);
rt.setRunning(false);
System.out.println("isRunning的值已经被设置了false");
}
}
在这个栗子中,创建子线程 rt 并启动后,就让主线程休眠 1s,让子线程 rt 运行,因为此时 isRunning为true,所以 rt 子线程会一直循环执行下去。当主线程休眠1s结束,将 isRunning的值改为了false,rt 子线程不在执行循环,rt子线程结束。执行结果为:

volatile虽然拥有多个线程之间的可见性,但是却不具备同步性(即原子性),一般volatile用于只针对多个线程可见的变量操作,并不能代表synchronized的同步操作。
举个栗子:
package com.song.test;
public class TestVolatile extends Thread {
public volatile static int n = 0;
public static void main(String[] args) {
TestVolatile t1 = new TestVolatile();
t1.start();
for (int i = 0; i < 200000; i++) {
n=n+1;
System.out.println(n);
}
}
public void run() {
for (int i = 0; i < 200000; i++) {
n=n+1;
System.out.println(n);
}
}
}
volatile 验证非原子性操作的栗子
在这个例子中,让 n 通过主线程和子线程分别加了两回,每次加了20000,如果是原子性操作那么n最终的值应该是400000,但实际上它的值是399998,因为它是非原子性的:
结果为:

那怎么用volatile关键字呢。对volatile修饰的变量要所有筛选:
变量的读写操作是独立的,不依赖其当前值(如 n=n+1),也不依赖于其他状态状态变量的共同参与与不变约束。
java线程学习之volatile关键字的更多相关文章
- java 线程Thread 技术--volatile关键字
java 语言中允许线程访问共享变量,为了保证共享变量能被准确和一致的更新,Java 语言提供了volatile 关键字,也就是我们所说的内存一致性: 问题抛出:(尝试去运行下面代码,以及将volat ...
- java线程学习之synchronized关键字
关键字synchronized的作用是实现线程间的同步.它的任务是对同步的代码加锁.一个代码块同时只能有同一个线程进行读和写操作,从而保证线程间是安全的. 线程安全的概念是:当多个线程访问某一个类(对 ...
- Java并发编程学习:volatile关键字解析
转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...
- Java并发编程:volatile关键字解析(学习总结-海子)
博文地址:Java并发编程:volatile关键字解析
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- 【转】Java并发编程:volatile关键字解析
转自:http://www.importnew.com/18126.html#comment-487304 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备 ...
- (转)Java并发编程:volatile关键字解析
转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...
- 《转》JAVA并发编程:volatile关键字解析
volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...
- Java并发编程:volatile 关键字
转自:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 其实Java语言是支持多线程的,为了解决线程并发的问题,在语言内部 ...
随机推荐
- Java中如何使用非强制类型转换把字符串转换成int类型
①强制类型转换代码如下: String string = "123456"; int a,b = 0; @Test public void String2Int1() { //方法 ...
- 寻找真正的入口(OEP)--广义ESP定律
1.前言 在论坛上看到很多朋友,不知道什么是ESP定律,ESP的适用范围是什么,ESP定律的原理是什么,如何使用ESP定律?看到了我在“”调查结果发现,大家对ESP定律很感兴趣,当然因为实在是太好用了 ...
- 2019OO第一单元总结
第一次作业 (你没看错,就一个类...) 通过正则表达式处理输入的字符串,提取出每一项的系数和指数,在输出的时候,应当考虑到合并同类项和正项提前的问题,使得最终的输出最短. 我第一次作业的代码超级难看 ...
- HTTP Streaming Architecture HLS 直播点播 HTTP流架构
小结: 1. 3部分 服务器组件 分发组件 客户端组件 https://developer.apple.com/library/archive/documentation/NetworkingInte ...
- css table之合并单元格
colspan 是合并列,rowspan是合并行,合并行的时候,比如rowspan="2",它的下一行tr会少一列:合并列的时候 colspan="2",此行的 ...
- Nginx(一)-windows下的安装配置
第一步 下载 官网下载地址 因为只是测试这里选择最新版本1.13.9 下载完成得到zip压缩包 解压后得到如下目录 第二步 启动nginx 注意不要直接双击nginx.exe,这样会导致修改配置后重 ...
- 64IE无法显示网页
1.碰到如下图情况ie浏览器打开之后显示不了网页,但是试了下电脑上其他的浏览器都可以正常的打开网页. 2.解决办法为:打开浏览器-选择“工具”-“Internet选项”-“高级”-重置,重启浏览器后能 ...
- go 学习第一个hello world 遇到的问题
mac:Go安装和配置+GoLand安装和使用之完整教程 https://blog.csdn.net/zxy_666/article/details/80182688 前言作为一个go语言程序员,觉得 ...
- 未能执行URL
在 <compilation debug="true"> 下 加入: <buildProviders> <add extension=".h ...
- com.mysql.jdbc.connection和java.sql.connection的区别
com.mysql.jdbc.Connection 是mysql自己的接口 针对于对mysql的出来,java.sql.Connection 这是一个公共的接口包括对mysql的支持oracle,sq ...