理解JMM

JMM

对volatile的理解

volatile 是java虚拟机提供轻量级的同步机制

1、保证可见性

2、不保证原子性

3、禁止指令重排

那么可见性与JMM相关

什么是JMM

Java内存模型,不存在的东西,是一个概念,是一个约定

  • 线程加锁前,必须读取主存中最新值到工作内存中
  • 线程解锁前,必须立刻将共享变量刷回到主存中
  • 加锁与解锁必须是同一把锁

解释:线程操作变量时,

1、是先将主存中的数据复制到自己的工作内存中

2、对自己内存的内容进行操作

3、操作完成后解锁时,需要将更新的内容,同步更新到主存中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

会存在一个问题,

  • 如果线程A读取了数据,但是没有停止,没有将数据刷新到主存中

  • 线程B读取了数据,并且一下就停止了,然后将数据刷新回了

  • 这个时候主存中的数据已经刷新了,但是工作内存中并没有得到最新的数据

所以volatile可以解决的,他可以让主存的数据变成可见性,也就是主存的数据如果发生了改变,就可以将数据直接刷新回去

上述就是保证了可见性

不保证原子性

  • 原子性操作是像原子一样,要么一起成功,要么一起失败

  • 但是volatile在变量上时,是不保证的。

    • 如何理解这句话

    • 举例

    • class X {private static int num;public static void add(){num++;}public static void main(String[] args) {for (int i = 0; i < 10; i++) {new Thread(()->{add();}).start();}System.out.println(num);}
      }
      
    • 上述代码一看就知道是存在数据不安全的情况

    • 那么在这里底层上num++,并不是一个操作,而是由多个步骤操作实现的num++;

    • 所以当出现了多个线程操作同一个变量时,就存在了不安全的行为,这几个步骤不能保证原子性

    • 而此时,添加了volatile也是没有办法保证原子性的

    • 注意:如果你把sout写到了里面,那么就会保证原子性,因为sout是加锁的

如何解决这个问题

使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个包下的内容

public static void add(){num.getAndIncrement();
}
public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 10; i++) {new Thread(()->{add();}).start();}while (Thread.activeCount() > 2){Thread.yield();}System.out.println(num);
}
  • 为什么要使用线程礼让
  • 这个线程如果都跑完了,就剩下main线程与gcc垃圾线程
  • 所以没有跑完就一直礼让
  • 保证最后执行sout
  • 也可以使用sleep休眠
  • 不然上面的线程还没有执行完,就输出了
  • 注意上面的问题哦

禁止指令重排

什么是指令重排

int x = 1;
int y = 2;
x = x + 2;
y = y + 2;
  • 这里,使用 第一个指令与第二个指令重新排队,对程序是没有影响的

会出现的问题

x , y ,a ,b = 0

线程A线程B
x = ay = b
b = 1a = 2

正常线程输出是

x = 0 b = 1 ; y = 1 a = 2

但是如果执行顺序不同,使得指令重排,

结果可能是

x = 2 b = 1 ; y = 1 a = 2;

那么volatile会禁止重新排列

为什么会出现禁止重排,因为内存屏障会

内存屏障禁止重排

保证数据可见性

在这里插入图片描述

  • volatile会增加数据禁止重排

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/1548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uni-app 如何添加模拟器

uni-app 如何添加模拟器 使用微信开发者工具运行微信小程序使用 HBuilderX 内置模拟器使用第三方 Android 模拟器 下载并安装&#xff1a;配置环境&#xff1a;连接模拟器&#xff1a; 总结 有哪些可以使用的安卓模拟器软件 uni-app 如何添加模拟器 Uni-App 是一个基于 Vue.js…

认知觉醒 PDF电子版 下载

认知觉醒 PDF电子版 开启自我改变的原动力 周岭 / 人民邮电出版社 / 2020-10 链接&#xff1a;https://pan.baidu.com/s/1EHUK_AhvE5TWAZsYXFQ5QA?pwdwrho 提取码&#xff1a;wrho

基于IIoT的设备预测性维护设计

基于IIoT的设备预测性维护设计 一、引言 在工业物联网&#xff08;IIoT&#xff09;的背景下&#xff0c;设备预测性维护成为了一种关键的战略&#xff0c;能够帮助企业提前发现并解决设备故障&#xff0c;从而提高生产效率、减少停机时间&#xff0c;并降低总体维护成本。为了…

uniapp 如何区分目前运行环境(app、web、mp-weixin)

platform 区分 iOS、Android uniplatform 区分 app、web、mp-weixin ....

Stable Diffusion,controlnet扩展

stable-diffusion-webui,GitHub地址&#xff1a; ControlNet-v1-1 版本模型下载&#xff1a; lllyasviel/ControlNet-v1-1 at main (huggingface.co) ControlNet-v1-1版本&#xff0c;GitHub地址&#xff1a; GitHub - lllyasviel/ControlNet-v1-1-nightly: Nightly releas…

前端实现以及个人理解

前言 这回从前端文本基础实现讲解开始&#xff0c;到前端本人使用过的一些框架进行简单说明&#xff0c;技术方面不会深讲&#xff0c;工作经验没多少&#xff0c;主要还不是固定一个方向深耕&#xff0c;本人一直觉得很慌&#xff0c;虽说领导给定的方向是全栈&#xff0c;但还…

控制maven 输出信息的语言

设置javac 输出 set JAVA_TOOL_OPTIONS-Duser.languageen JAVA_TOOL_OPTIONS-Duser.languageen 如果用java/java.exe来启动JVM&#xff0c;那么在命令行上使用 -Duser.countryUS 就可以把国家指定为美国。用javac/javac.exe来启动javac编译器则需要再多加个-J在前面&#xff0…

GPT-3.5 Turbo 的 temperature 设置为 0 就是贪婪解码?

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 将 GPT-3.5 Turbo 的 temperature 设置为 0 通常意味着采用贪婪解码&#xff08;greedy decoding&#xff09;策略。在贪婪解码中&#xff0c;模型在每一步生成文本时选择概率最高的词元&#xff0c;从…

【Linux】学习记录_15_POSIX信号量

15 POSIX信号量 15.1 POSIX信号量基本概念 信号量&#xff08;Semaphore&#xff09;是一种实现进程/线程间通信的机制&#xff0c;可以实现进程/线程之间同步或临界资源的互斥访问&#xff0c; 常用于协助一组相互竞争的进程/线程来访问临界资源。在多进程/线程系统中&#…

Microchip 32位MCU CAN驱动图文教程-附源码

文章目录 创建一个新的32位MCU工程Microchip MCC Harmony配置界面说明在MCC下配置系统的时钟在MCC下配置所需要使用的模块配置调试打印模块配置CAN模块配置管脚功能修改系统堆栈大小生成代码 添加用户代码 创建一个新的32位MCU工程 确保电脑上已经安装最新的MPlab X IDE、XC32编…

ubuntu安装QEMU

qemu虚拟机的使用&#xff08;一&#xff09;——ubuntu20.4安装QEMU_ubuntu安装qemu-CSDN博客 遇到的问题&#xff1a; (1)本来使用git clone https://github.com/qemu/qemu.git fatal: 无法访问 https://github.com/qemu/qemu.git/&#xff1a;GnuTLS recv error (-110): …

使用 ADB 命令在 Android 设备上进行截屏

在 Android 开发和调试过程中&#xff0c;截取设备屏幕是一项非常有用的功能。ADB&#xff08;Android Debug Bridge&#xff09;是一个强大的工具&#xff0c;可以帮助我们与 Android 设备进行通信和调试。本文将介绍如何使用 ADB 命令在 Android 设备上进行截屏。 1. 准备工…

[阅读笔记18][CITING]LARGE LANGUAGE MODELS CREATE CURRICULUM FOR INSTRUCTION TUNING

这篇论文是23年10月提交到arxiv上的&#xff0c;也是用大模型蒸馏小模型的思路。 作者在这篇论文中提出了课程指令微调&#xff0c;大体流程如下图所示&#xff0c;教师模型给出一个问题&#xff0c;让学生模型回答一下&#xff0c;这时候学生回答大概率不够准确&#xff0c;这…

简化安卓操作:利用ADB命令返回主页、首页等操作

介绍&#xff1a; 在日常使用安卓设备时&#xff0c;经常需要返回到主页或者首页。虽然通过手动点击设备上的按钮可以轻松实现&#xff0c;但对于一些需要频繁进行此操作的场景&#xff0c;这种方式可能显得有些繁琐。幸运的是&#xff0c;利用ADB&#xff08;Android Debug Br…

深度学习之图像分割从入门到精通——基于unet++实现细胞分割

模型 import torch from torch import nn__all__ [UNet, NestedUNet]class VGGBlock(nn.Module):def __init__(self, in_channels, middle_channels, out_channels):super().__init__()self.relu nn.ReLU(inplaceTrue)self.conv1 nn.Conv2d(in_channels, middle_channels, …

生态短讯 | Tapdata 与 TDengine 完成产品兼容性互认证,打造物联网实时数据生态

近月&#xff0c;深圳钛铂数据有限公司&#xff08;以下简称钛铂数据&#xff09;自主研发的实时数据平台&#xff08;Tapdata Live Data Platform&#xff09;与北京涛思数据科技有限公司&#xff08;以下简称涛思数据&#xff09;自主研发的大数据平台 TDengine&#xff0c;已…

【深度学习】Dropout、DropPath

一、Dropout 1. 概念 Dropout 在训练阶段会让当前层每个神经元以drop_prob&#xff08; 0 ≤ drop_prob ≤ 1 0\leq\text{drop\_prob}\leq1 0≤drop_prob≤1&#xff09;的概率失活并停止工作&#xff0c;效果如下图。 在测试阶段不会进行Dropout。由于不同批次、不同样本的神…

数据库管理-第171期 Oracle是用这种方式确保读一致的(20240418)

数据库管理171期 2024-04-18 数据库管理-第171期 Oracle是用这种方式确保读一致的&#xff08;20240418&#xff09;1 基本概念2 用处3 注意事项总结 数据库管理-第171期 Oracle是用这种方式确保读一致的&#xff08;20240418&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#x…

MySQL中explain的用法

执行结果各字段的含义 EXPLAIN SQL语句 如&#xff1a; EXPLAIN SELECT * FROM test 执行结果&#xff1a; 列名描述id在一个大的查询语句中每个SELECT关键字都对应一个 唯一的idselect_typeSELECT关键字对应的那个查询的类型table表名partitions匹配的分区信息type针对单表…

P2P面试题

1&#xff09;描述一下你的项目流程以及你在项目中的职责&#xff1f; 一个借款产品的发布&#xff0c;投资人购买&#xff0c;借款人还款的一个业务流程&#xff0c;我主要负责测注册&#xff0c;登录&#xff0c;投资理财这三个模块 2&#xff09;你是怎么测试投资模块的&am…