并发编程基础之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();//线程1Thread t1 = new Thread("t1"){public void run(){while(!list.flag){System.out.println("i love u");}}};//线程2Thread 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个线程访问的是同一个实例,所以使用对象锁就可以了。
转载于:https://www.cnblogs.com/warrior4236/p/7531973.html
并发编程基础之volatile关键字的用法相关推荐
- 并发编程系列之volatile关键字详解
并发编程系列之volatile关键字详解 1.volatile是什么? 首先简单说一下,volatile是什么?volatile是Java中的一个关键字,也是一种同步机制.volatile为了保证变量 ...
- 【Java并发编程 】同步——volatile 关键字
英 /ˈvɒlətaɪl/ 我了太噢(记不住单词怎么读) 一.volatile的介绍? volatile是一个轻量级的synchronized,一般作用与变量,在多处理器开发的过程中保证了内存的可见性 ...
- Java并发编程的艺术-Java并发编程基础
第4章 Java并发编程基础 Java从诞生开始就明智地选择了内置对多线程的支持,这使得Java语言相比同一时期的其他语言具有明显的优势.线程作为操作系统调度的最小单元,多个线程能够同时执行,这将 ...
- python中并发编程基础1
并发编程基础概念 1.进程. 什么是进程? 正在运行的程序就是进程.程序只是代码. 什么是多道? 多道技术: 1.空间上的复用(内存).将内存分为几个部分,每个部分放入一个程序,这样同一时间在内存中就 ...
- 【牛客网】-【并发详解】-【并发编程基础】-【原子类】
目录 并发编程基础 原子类 参考书目: 并发编程基础 在操作系统中,并发是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处 ...
- Java并发编程基础--ThreadLocal
Java并发编程基础之ThreadLocal ThreadLocal是一个线程变量,但本质上是一个以ThreadLocal对象为键.任意对象为值的存储结构,这个结构依附在线程上,线程可以根据一个T ...
- java volatile 原子性_Java并发编程之验证volatile不能保证原子性
Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...
- Java并发编程学习笔记——volatile与synchronized关键字原理及使用
Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令. 一.vo ...
- Java并发编程 基础知识学习总结
Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容,这部分的内容我也是反复学习了好几遍才能理解.本篇博客梳理一下最近从<Java 并发编程的艺术>和他人的博客学习Java并发 ...
最新文章
- 51nod1092(lcs简单运用/dp)
- Windows Mobile Incoming Call View Custom
- 455. Assign Cookies - LeetCode
- 执行了的程序,才是你的程序.
- 遇到上亿(MySQL)大表的优化....
- VTK:高亮选择动画用法实战
- 构造类斐波那契数列矩阵
- 第三次学JAVA再学不好就吃翔(part77)--迭代器遍历
- ooooo123123emabc
- 基于汇编语言及Proteus仿真的CPU8086水库水位监视系统
- 编程语言对比 标准io
- Konomi与去中心化借贷协议bZx合作推动DeFi生态发展
- 海南关于推荐扬尘监控系统的通知_实时监管!定州对44家混凝土搅拌企业实施远程视频监控...
- 云监控中inode使用率监控具体作用是什么
- 某里巴巴Java工程师常规面试题以及解答
- html中图片阴影怎么写,css如何给图片加阴影?
- 如何在 GitHub 上面精准搜索开源项目?
- struts(二)——struts框架实现的基本原理
- 你想知道的JPype全在这里∞
- 程序员编程规范之注释