文章目录

  • 一、原子操作
  • 二、volatile 关键字使用场景

一、原子操作


原子操作 :

read : 从 主内存 中的线程共享变量中读取数据 ;
load : 将从主内存读取到的数据 , 加载到 线程工作内存 中 ;

read 和 load 操作一定是 成对出现 的 , 只要从主内存中读取到数据 , 一定会将这个数据加载到线程的工作内存中 ;

use : 从线程共享变量副本读取到线程的 执行引擎 中 ;
assign : 从执行引擎中写出数据到变量的 共享变量副本 中 ;

store : 将数据从线程工作内存传输到 主内存 中 ;
write : 将数据赋值给主内容中的线程 共享变量 ;

lock : 作用于 主内存中的线程共享变量 , 将该变量标识为 被某个线程独自占用状态 ; 表示该变量只有一个线程可以进行访问 ;
unlock : 解锁 主内存中的共享变量 , 其它线程可以进行访问 ;

二、volatile 关键字使用场景


在下面的示例中 , 设置一个标志位 , 主线程开始后 , 启动一个线程 , 休眠 100010001000 毫秒 , 然后修改该标志位 , 主线程中根据标志位进行循环 , 如果标志位被修改 , 则循环停止 , 但是循环一直没有停止 ;

也就是说线程中修改的值 , 仅修改了该线程中工作内存中的标志位副本的值 ;

主内存中的值没有被修改 ;

代码示例 :

public class Main {private static boolean flag = false;private static void changeFlag() {System.out.println("修改标志位开始");flag = true;System.out.println("修改标志位结束");}public static void main(String[] args) {// 在该线程中 , 1 秒后修改标志位为 falsenew Thread(){@Overridepublic void run() {super.run();try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}changeFlag();}}.start();// 此处如果 flag 一直为 flase 就会进入死循环//      如果 flag 为 true 则程序结束while (!flag) {}System.out.println("主线程结束");}
}

执行结果 :

原理分析 :

线程的工作内存中 , 将 flag 修改为 true , 这只是在 CPU 缓存 中修改的 , 没有在主内存中修改这个共享变量值 , 因此主线程访问该值 , 还是 false ;

使用 volatile 关键字 , 禁用 CPU 的缓存 , 直接在主内存中进行读写 , 这样就可以解决多个线程中 共享变量 不同步的问题 ;

注意 : 只能是 线程共享变量 使用该关键字 , 设置该关键字会影响线程的执行效率 , 效率会降低 ;

使用了 volatile 关键字后的效果 :

public class Main {private static volatile boolean flag = false;private static void changeFlag() {System.out.println("修改标志位开始");flag = true;System.out.println("修改标志位结束");}public static void main(String[] args) {// 在该线程中 , 1 秒后修改标志位为 falsenew Thread(){@Overridepublic void run() {super.run();try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}changeFlag();}}.start();// 此处如果 flag 一直为 flase 就会进入死循环//      如果 flag 为 true 则程序结束while (!flag) {}System.out.println("主线程结束");}
}

执行结果 :

Java 并发的 333 特性 :

  • 原子性 : 每个操作都是 不可拆分的原子操作 ; 在线程中进行 a++ 就不是原子操作 , 该操作分为 333 个步骤 , 首先从主内存中读取 a 变量 , 然后进行自增操作 , 最后在将自增后的值写回主内存中 ;
  • 可见性 : 多个线程 访问同一个变量 , 该变量一旦被 某个线程修改 , 这些线程必须可以 立刻看到被修改的值 ;
  • 有序性 : 程序按照 代码先后顺序 执行 ;

volatile 关键字 , 禁用了 CPU 缓存 , 解决的是共享变量可见性问题 ;

【Java 并发编程】线程简介 ( 原子操作 | volatile 关键字使用场景 )相关推荐

  1. Java并发编程:JMM和volatile关键字

    Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内置高速缓存区.高速缓存区的加入使得CP ...

  2. Java 并发编程 -- 线程池源码实战

    一.概述 小编在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写的太简单,只写了一点皮毛,要么就是是晦涩难懂,看完之后几乎都 ...

  3. Java并发编程(三)volatile域

    相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Android多线程(一)线程池 Android多线程(二)AsyncTask源代码分析 前言 有时仅仅为了读写一个或 ...

  4. 进阶笔记——java并发编程三特性与volatile

    欢迎关注专栏:Java架构技术进阶.里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦.微信公众号:慕容千语的架构笔记.欢迎关注一起进步. 前言 前面讲过使用synchronize ...

  5. Java并发编程—线程间协作方式wait()、notify()、notifyAll()和Condition

    原文作者:Matrix海 子 原文地址:Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 目录 一.wait().notify()和notifyA ...

  6. Java并发编程-线程安全基础

    线程安全基础 1.线程安全问题 2.账户取款案例 3.同步代码块synchronized synchronized的理解 java中有三大变量的线程安全问题 在实例方法上使用synchronized ...

  7. Java并发编程——线程池的使用

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...

  8. java workerdone_【架构】Java并发编程——线程池的使用

    前言 如果我们要使用线程的时候就去创建一个,这样虽然非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为 ...

  9. JAVA并发编程-线程安全性

    线程安全性:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程如何交替执行,并且在主调代码中不需要任何额外的同步或协同,各个类都能表现出正确的行为,那么称这个类是线程安全的. 1.原子 ...

最新文章

  1. 设计模式原则--单一职责原则
  2. C#抓取网页程序的实现浅析
  3. 转 android anr 分析示例,[摘]Android ANR日志分析指南之实例解析
  4. java应用部署docker_Docker部署JavaWeb项目实战
  5. freeradius 3.0 时间限制_创意营销3.0新模式下,易企秀要成为中国的Adobe
  6. BugkuCTF-PWN题canary超详细讲解
  7. hive整合ldap权限管理
  8. jQuery入门第三天
  9. python开源项目2019_2019年6月Github上最热门的Python开源项目
  10. 8.3 折特惠票仅剩 5 天!「2019 嵌入式智能国际大会」全日程大公开!
  11. java21天打卡-day14 日期时间
  12. Python学习手册之类和继承
  13. ConurrentHashMap和Hashtable的区别
  14. 软件案例分析-音乐软件界的卧龙凤雏-酷狗音乐与网易云音乐
  15. 暴风影音2009 Real插件无法下载安装问题解决
  16. 广州传智播客.net一期训练营学习感悟(一)求学之路
  17. word 单独设置正文页码
  18. cd短是什么意思,王者荣耀:是不是技能cd越短难度就越大?看她就明白了
  19. 防沉迷与身份证系统挂钩 网游要实名认证
  20. 华为Mate 20 Pro拆解、iPhone XR 拆解、iPhone XS/XS Max拆解

热门文章

  1. python requests的安装与简单运用
  2. C#连接ORACLE数据库乱码问题
  3. HP—UX更改存储设备名
  4. Iphone 指触行为会
  5. 【Vegas原创】添加SQL Server Agent作业步骤中的运行身份
  6. 打开 XP Pro SP2 远程桌面的多用户支持
  7. Angular\Vue解决页面数据加载时出现{{message}}闪烁的情况
  8. Python基础(1) - 初识Python
  9. Android ListView 横向滑动删除 Item
  10. 【JavaScript】jQuery绑定事件