JUC并发编程学习笔记(十五)JMM
JMM
请你谈谈对Volatile的理解
Volatile是java虚拟机提供的轻量级的同步机制
1、保证可见性
2、不保证原子性
3、禁止指令重排
什么是JMM
JVM->java虚拟机
JMM->java内存模型,不存在的东西,概念!约定
关于JMM的一些同步的约定:
线程解锁前,必须把共享变量立刻刷回主存

线程加锁前,必须读取主存中的最小值到工作内存中!
必须要保证加锁和解锁时同一把锁
线程------->工作内存、主内存


详见:Java内存模型(JMM)详解 - 程序新视界 - 博客园 (cnblogs.com)
在此交互过程中,Java内存模型定义了8种操作来完成,虚拟机实现必须保证每一种操作都是原子的、不可再拆分的(double和long类型例外)。
- lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态。
- unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
- read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用。
- load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
- use(使用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作。
- assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。
- store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的write操作使用。
- write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。
Java内存模型还规定了在执行上述8中基本操作时必须满足如下规则。
- 不允许read和load、store和write操作之一单独出现,即不允许一个变量从主内存读取了但工作内存不接受,或者从工作内存发起回写了但主内存不接受的情况出现。
- 不允许一个线程丢弃它的最近的assign操作,即变量在工作内存中改变了之后必须把该变化同步回主内存。
- 不允许一个线程无原因地(没有发生过任何assign操作)把数据从线程的工作内存同步回主内存。
- 一个新的变量只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量,换句话说,就是对一个变量实施use、store操作之前,必须先执行过了assign和load操作。
- 一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。
- 如果对一个变量执行lock操作,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值。
- 如果一个变量事先没有被lock操作锁定,那就不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定住的变量。
- 对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store、write操作)。
模拟主内存中数据被修改后未能获取到最新数据的子线程的工作内存状态
package org.example.tvolatile;
import java.util.concurrent.TimeUnit;
public class JMMDemo01 {
//定义变量
private static Integer num = 0;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
//只要num=0就一直循环,来模拟主线程数据被改变后子线程的状态
while (num==0){
}
System.out.println("子线程执行结束,num已经不等于0了");
}).start();
//休眠疫苗等待子线程开启
TimeUnit.SECONDS.sleep(1);
//修改值
num=1;
System.out.println(num);
}
}
结果就是当主内存中的值已经被改变了,但是子线程中的工作内存不知道,所以还在一直循环

程序一直没有结束!
问题:子线程中的工作内存不知道主内存的值已经被修改过了
------------------>引出Volatile,Volatile就能解决这个问题
JUC并发编程学习笔记(十五)JMM的更多相关文章
- JUC并发编程学习笔记
JUC并发编程学习笔记 狂神JUC并发编程 总的来说还可以,学到一些新知识,但很多是学过的了,深入的部分不多. 线程与进程 进程:一个程序,程序的集合,比如一个音乐播发器,QQ程序等.一个进程往往包含 ...
- 并发编程学习笔记(6)----公平锁和ReentrantReadWriteLock使用及原理
(一)公平锁 1.什么是公平锁? 公平锁指的是在某个线程释放锁之后,等待的线程获取锁的策略是以请求获取锁的时间为标准的,即使先请求获取锁的线程先拿到锁. 2.在java中的实现? 在java的并发包中 ...
- Java并发编程学习笔记
Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现R ...
- 并发编程学习笔记(8)----ThreadLocal的使用及源码分析
1. ThreadLocal的理解 ThreadLocal,顾名思义,就是线程的本地变量,ThreadLocal会为每个线程创建一个本地变量副本,使得使用ThreadLocal管理的变量在多线程的环境 ...
- 并发编程学习笔记(4)----jdk5中提供的原子类及Lock使用及原理
(1)jdk中原子类的使用: jdk5中提供了很多原子类,它会使变量的操作变成原子性的. 原子性:原子性指的是一个操作是不可中断的,即使是在多个线程一起操作的情况下,一个操作一旦开始,就不会被其他线程 ...
- python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...
- 并发编程学习笔记(15)----Executor框架的使用
Executor执行已提交的 Runnable 任务的对象.此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节.调度等)分离开来的方法.通常使用 Executor 而不是显式地创建 ...
- 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理
1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...
- 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理
· 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...
- 并发编程学习笔记(11)----FutureTask的使用及实现
1. Future的使用 Future模式解决的问题是.在实际的运用场景中,可能某一个任务执行起来非常耗时,如果我们线程一直等着该任务执行完成再去执行其他的代码,就会损耗很大的性能,而Future接口 ...
随机推荐
- 手写raft(一) 实现leader选举
1. 一致性算法介绍 1.1 一致性同步与Paxos算法 对可靠性有很高要求的系统,通常都会额外部署1至多个机器为备用副本组成主备集群,避免出现单点故障. 有状态的系统需要主节点与备用副本间以某种方式 ...
- go install 和 go get的区别
go install 和 go get 都是 Go 语言中的命令行工具,用于处理依赖关系和安装包.它们的主要区别在于功能和使用场景. go install: 功能:go install 命令用于编译并 ...
- 关于在modelsim中 仿真 ROM IP核 读取不了 mif文件 的解决方法
在modelsim中 仿真 ROM IP核 读取不了 mif文件 . 出现状况: 显示无法打开 rom_8x256.mif 文件 .点开modelsim下面文件的内存列表,可看到内存全为0. 查看自身 ...
- 基于inotify-tools和rsync实现文件实时同步
前言 系统:centos 7 inotify-tools版本:3.14(3.22版本测试有问题,所以找的比较旧的一版) 主机IP: 192.168.137.7(服务端,接收同步文件) 192.168. ...
- C#利用Refit实现JWT自动续期
前言 笔者之前开发过一套C/S架构的桌面应用,采用了JWT作为用户的登录认证和授权.遇到的唯一问题就是JWT过期了该怎么办?设想当一个用户正在进行业务操作,突然因为Token过期失效,莫名其妙地跳转到 ...
- 三维模型OBJ格式轻量化压缩变形现象分析
三维模型OBJ格式轻量化压缩变形现象分析 三维模型的OBJ格式轻量化压缩是一种常见的处理方法,它可以减小模型文件的体积,提高加载和渲染效率.然而,在进行轻量化压缩过程中,有时会出现模型变形的现象,即压 ...
- 用OLED屏幕播放视频(1): 项目介绍
下面的系列文章记录了如何使用一块linux开发扳和一块OLED屏幕实现视频的播放: 项目介绍 为OLED屏幕开发I2C驱动 使用cuda编程加速视频处理 这篇文章主要对项目的实现做整体的介绍, 包括硬 ...
- HarmonyOS 4.0 实况窗上线!支付宝实现医疗场景智能提醒
本文转载自支付宝体验科技,作者是蚂蚁集团客户端工程师博欢,介绍了支付宝如何基于 HarmonyOS 4.0 实况窗实现医疗场景履约智能提醒. 1.话题背景 8 月 4 日,华为在 HDC(华为 202 ...
- Java 21新特性:Sequenced Collections(有序集合)
在JDK 21中,Sequenced Collections的引入带来了新的接口和方法来简化集合处理.此增强功能旨在解决访问Java中各种集合类型的第一个和最后一个元素需要非统一且麻烦处理场景. 下面 ...
- 内网离线安装docker并配置使用nexus为docker私服
背景 本文简单记录下最近在内网服务器离线安装docker及配置nexus作为docker私服,踩的一些坑.docker和k8s这块技术我跟得不是很紧,18年的时候用过一阵docker,后来发现它并不能 ...