并发编程基础之volatile关键字的用法
一:概念
volatile关键字是一个轻量级的线程同步,它可以保证线程之间对于共享变量的同步,假设有两个线程a和b,
它们都可以访问一个成员变量,当a修改成员变量的值的时候,要保证b也能够取得成员变量最新的值,程序的
内存模型是这样的,程序运行时,成员变量的值被加载到内存中,如果线程a运行时,会把变量的值拷贝到cpu分配
给a的高速缓存区,就是内存的一个副本,线程b运行时,会把变量拷贝到cpu分配给b的高速缓存区,正常情况下,
a线程修改成员变量时,会将高速缓存中的值写入主存,然后b线程运行时读取主存中值到缓存,但是不是强制性的,
使用volatile关键字就是强制性。
1:将高速缓存强制写入主内存
2:会使b线程高速缓存标记失效
二:比较经典的一个示例
t1线程先启动,然后一直打印‘i love u’,这时t2线程启动,将flag变量的值修改为true,然后t1线程的执行终止,如果flag变量不加volatile修饰,
出现死循环的概率是存在的,但是比较低,如果加volatile,会强制t2线程修改主内存中flag的值,而且t1线程高速缓存标记会失效,可以保证
一定能够终止t1程序的执行
/**
*
*/
package com.day2; /**
* @author Administrator
*
*/
public class ListAdd1 { private boolean flag; public static void main(String[] args) {
ListAdd1 list = new ListAdd1(); //线程1
Thread t1 = new Thread("t1"){
public void run(){
while(!list.flag){
System.out.println("i love u");
}
}
}; //线程2
Thread t2 = new Thread("t2"){
public void run(){
list.flag = true;
}
}; t1.start();
//保证t1线程先启动
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
} }
private volatile boolean flag;
但是volatile并不能保证操作的原子性,线程抢到cpu的时间片,修改高速缓存的值,写入主内存这几个过程不是原子的,
int i = 0;
i = i+1;
如果线程1在抢到cpu的时间片之后,还没有修改高速缓存的值,然后线程2也读取了主内存中缓存的值i = 0,然后执行加1,
写入高速缓存,线程1之前读取缓存中的值也是0,然后执行加1,写入主内存,这样就出现问题了,所以使用volatile不能
保证线程安全问题。
如下示例:
启动10个线程,count初始值为0,正常情况,10个线程个循环1000次,最后的count值应该为10000,但是不是,这个值
是随机的。
/**
*
*/
package com.day2; /**
* @author Administrator
*
*/
public class ListAdd2 { private volatile int count; public static void main(String[] args) {
ListAdd2 list = new ListAdd2(); System.out.println(list.count); for(int i=0;i<10;i++){
new Thread("t"+i){
public void run(){
for(int j=0;j<1000;j++){
list.count++;
}
}
}.start();
} System.out.println(list.count);
} }
如果想确保线程安全,那么必须使用synchronized锁
synchronized (list) {
list.count++;
}
因为10个线程访问的是同一个实例,所以使用对象锁就可以了。
并发编程基础之volatile关键字的用法的更多相关文章
- Java并发编程之三:volatile关键字解析 转载
目录: <Java并发编程之三:volatile关键字解析 转载> <Synchronized之一:基本使用> volatile这个关键字可能很多朋友都听说过,或许也都用过 ...
- Java并发编程学习:volatile关键字解析
转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...
- Java并发编程基础之volatile
首先简单介绍一下volatile的应用,volatile作为Java多线程中轻量级的同步措施,保证了多线程环境中“共享变量”的可见性.这里的可见性简单而言可以理解为当一个线程修改了一个共享变量的时候, ...
- Java并发编程(二):volatile关键字
volatile是Java虚拟机提供的轻量级的同步机制.volatile关键字有如下两个作用,一句话概括就是内存可见性和禁止重排序. 1)保证被volatile修饰的共享变量对所有线程总是可见的,也就 ...
- Java并发编程知识点总结Volatile、Synchronized、Lock实现原理
Volatile关键字及其实现原理 在多线程并发编程中,Volatile可以理解为轻量级的Synchronized,用volatile关键字声明的变量,叫做共享变量,其保证了变量的“可见性”以及“有序 ...
- Java并发编程系列-(1) 并发编程基础
1.并发编程基础 1.1 基本概念 CPU核心与线程数关系 Java中通过多线程的手段来实现并发,对于单处理器机器上来讲,宏观上的多线程并行执行是通过CPU的调度来实现的,微观上CPU在某个时刻只会运 ...
- Java并发编程基础
Java并发编程基础 1. 并发 1.1. 什么是并发? 并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互 ...
- python中并发编程基础1
并发编程基础概念 1.进程. 什么是进程? 正在运行的程序就是进程.程序只是代码. 什么是多道? 多道技术: 1.空间上的复用(内存).将内存分为几个部分,每个部分放入一个程序,这样同一时间在内存中就 ...
- 并发-Java并发编程基础
Java并发编程基础 并发 在计算机科学中,并发是指将一个程序,算法划分为若干个逻辑组成部分,这些部分可以以任何顺序进行执行,但与最终顺序执行的结果一致.并发可以在多核操作系统上显著的提高程序运行速度 ...
随机推荐
- [P1879][USACO06NOV]玉米田Corn Fields (状态压缩)
最近题目都有状态压缩,我是蒟蒻,并不会状态压缩 然后我决定学了! 然后发现我学不来. OI-WIKI上的界面给我推荐了这道题https://oi-wiki.org/dp/state/ 状态压缩入门题, ...
- 受欢迎的牛 [HAOI2006] [强连通] [传递闭包(划)]
Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛 A 认为牛 B受欢迎.这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A ...
- 种花 [JZOJ4726] [可撤销贪心]
Description 经过三十多个小时的长途跋涉,小Z和小D终于到了NOI现场——南山南中学.一进校园,小D就被花所吸引了(不要问我为什么),遍和一旁的种花园丁交(J)流(L)了起来. 他发现花的摆 ...
- goland 中国 caisy qq Czx123456
goland 中国 caisy qq Czx123456
- Myeclispe下struts-config.xml文件无法图形界面打开
1.今天更改web.xml文件不小心误删了下面的配置文件,导致出现如图的错误 <servlet-mapping> <servlet-name>action</servle ...
- python之编程风格
第一:语句和语法 # 表示注释掉的内容 \ 续行 print("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\ yyyyyyyyyyyyyyyyyyyyy ...
- Elastic{ON}参会随手记
Elastic{ON} 同事送了一张Elastic{ON}的票,因为我们的产品中用到的ELK全家桶,实话说用的体量还挺大的,因此非常想去参加这次的发布会. 7.0的新特性 上午的会议是来自总部的一名工 ...
- 解决Everything1.4版本预览时不支持自定义后缀的问题
2017年6月Everything版本升级到了1.4.x 个人使用下来认为最主要的有以下几点 添加预览功能 搜索结果多选 点击目录列即打开文件所在目录(需要设置:常规->结果->双击路径列 ...
- 【问题与解决】showModalDialog is not defined 的解决方案
背景: showModalDialog 是比较老的方法了,有些浏览器不再支持弹出模态窗口了. 比如说谷歌浏览就不再支持了,有文章说明如下: Chrome’s Lack of Support for s ...
- 新版本的bettercap不好用, 如何安装和编译旧版本的bettercap
新版本的bettercap2.0以上是用go语言写的, 各种功能感觉还不太完善, 没有原来的用ruby写的好, 想着回退安装bettercap1.6旧版本 系统环境: kali 2017.2 下载源码 ...