并发编程_jmm部分

news2024/11/16 1:23:53

1. JMM 理解

前提:并发编程有3大问题,可见性、有序性、原子性。
导致可见性的原因是缓存,有序性的原因是 编译器优化。解决方法就是直接禁用缓存和编译器优化,导致程序性能堪忧。
因此合理的方案就是按需禁用缓存和编译器优化。

所以: java 内存模型针对在多线程环境下,可见性 有序性制定了一些规范,在jvm 层面 提供按需禁用缓存和编译优化的方法。具体就是使用synchronized,volatile,final三个关键字和Happens-before 规则。 解决并发编程中 的代码的有序性和可见性。

long double 32位原子性问题。

3
如果需要保证 long 和 double 在 32 位系统中原子性,需要用 volatile 修饰

load load 两个连续的读不要重排序 防止读跑上去

防止 B 的 Load 重排到 A 的 Load 之前

if(A) {
    LoadLoad
    return B
}

read(A)
LoadLoad
read(B)
  • 意义:A == true 时,再去获取 B,否则可能会由于重排导致 B 的值相对于 A 是过期的
    3

loadstore 防止连续 读写 防止写跑上去。

3

Acquire 第一个是load,防止后续的 读、写 不要重排序

同一线程内,读 操作之后的的读写,上不去,同时第一个load能读到主存中的最新值。
3

store store 连续的写 防止写跑下来

  • 防止 A 的 Store 被重排到 B 的 Store 之后
A = x
StoreStore
B = true
  • 意义:在 B 修改为 true 之前,其它线程别想看到 A 的修改
    • 有点类似于 sql 中更新后,commit 之前,其它事务不能看到这些更新(B 的赋值会触发 commit 并撤除屏障)
      3

release 防止读和写 跑下来。 ss ls

同一线程内,写操作之前的 , 读写下不来,后面的store 都能将改动的 都写入主存。
store store
load sore
防止上面的 读操作 写操作,被重排序到 写操作下面
3

store load ** 发生在线程切换时有效。 保证可见性。

sotre load 屏障 在线程切换时,保证可见性。

意义:屏障前的改动都同步到主存,屏障后的 Load 获取主存最新数据

  • 防止屏障前所有的写操作,被重排序到屏障后的任何的读操作,可以认为此 store -> load 是连续的
  • 有点类似于 git 中先 commit,再远程 poll,而且这个动作是原子的
    3

2.volatile 本质

写变量时 加 loadstore store store 屏障 和 store load 屏障

红色 蓝色是两个线程。
a

读取变量时 load load ,load store

在变量加入load load load store 屏障
3

1. 保证单一变量赋值的原子性

32 位操作系统,long double

2. 保证变量的有序性

线程内通过内存屏障保证有序,线程切换按照happen-before 有序。

partial ordering

total ordering

3. 可见性

线程切换时 ,发生了写->读,则变量可见,顺便影响普通变量可见性。
在volatile 变量 加入store load 屏障。
红色线程的写入同步到主存,然后让蓝色线程的读取,取主存中读取最新值。
3

3. Synchronization order

线程内部的一个顺序

4.happen-before 原则

在线程切换时,代码的顺序 和可见性。

表达的是,前一个线程的操作的结果 对后续线程的操作是可见的。

线程启动 和运行边界

线程1 启动线程2前对共享变量进行修改,在线程2运行时,读取共享变量一定能看到修改。
3

线程的结束 和join 的边界。

线程1 结束前,对共享变量的修改。t2线程等待t1线程的解释 join,t2也能读取到共享变量的读取。

线程的打断 和得知线程的打断。

interrupt
t1线程修改共享变量,t1线程对t2线程打断,t2线程得知打断,能够读取到共享变量的改变。
3

unlock 和lock 边界。

t1线程解锁前对共享变量的修改,t2线程加锁后,能够读取到共享变量的修改。

volatile 对变量的写 和volatile 的读 的边界

传递性

如果a hb b,
b hb c,
那么有a hb c

5. cas 原理

使用乐观锁机制,保证变量读写的原子性。
volatile+ cas 实现原子 可见 有序
volatile 搭配cas 保证 共享变量的可见性。
线程数小于cpu 核心数,乐观锁性能高。

aqs 的state 使用volatile

cas + volatile 保证 state 的最新值 和 互斥。

concurrenthashmap 懒惰初始化

有一个sizectl 属性,volatile 修饰,保证可见性。
在第一次 put 时,检查sizectl,使用cas 把 0 改成 -1, (-1,hash表正在被初始化),
其他线程来 初始化 cas 失败,不会重复创建了。

6. synchronized

有序性

3
在monitor enter 和 monitor exit 加了相应的屏障,
保证了 同步代码块 内部的代码,共享变量的读写, 不会重排序到同步代码块的外面。
强调 :
但是 在同步代码块内部还是会存在重排序的。

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

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

相关文章

MySQL数据库——单表查询练习

一、练习素材 创建表 CREATE TABLE emp (empno int(4) NOT NULL,ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,mgr int(4) NULL DEFAULT NULL,hireda…

遗传算法核心理解,python代码

遗传算法的核心,就在于,把待求的变量转化成二进制串,二进制串就像dna,可以对它的其中某几位进行交换,变异等操作,然后再转换回十进制,带入目标函数,计算适应度,保留适应度…

【lambda函数】lambda()函数

lambda() lambda()语法捕捉列表mutable lambda 底层原理函数对象与lambda表达式 lambda()语法 lambda表达式书写格式: [capture-list] (parameters) mutable -> return-type{ statement }咱…

【数据结构】排序:插入排序与希尔排序详解

本章开始就要分享一些常用的排序方法,我们的日常生活中很多地方都要使用排序,比如电商平台可以按照你的需求进行排序,或者是你想了解大学的综合排名时 我们之前也学到过一些简单的排序比如冒泡排序,虽然他在时间复杂度上可以说是依…

归并排序(思路+代码)

变量: left、right、privot、temp[]、leftIndex、k 思路: 代码: import java.util.Arrays;public class Queue8 {public static void main(String[] args) {int[] arr {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};sort(arr,0,arr.length-1);System.ou…

AST-抽象语法树

js加密解混淆首先想到的是AST语法树,那么什么是AST呢,学习AST过程的一些笔记 1.AST是JS执行的第一步是读取 js 文件中的字符流,然后通过词法分析生成令牌流Tokens,之后再通过语法分析生成 AST(Abstract Syntax Tree&a…

3D 旋转木马

在工作中我们常用到3D装换和3D位移 主要知识点 3D位移:transale3d(x,y,z)3D旋转:rotate3d(x,y,z)透视:perspective3D呈现 transfrom-style 1、 transale3d translform: translform:translateX(100px):仅仅是在x轴上移动translform:transl…

[NOI2014] 随机数生成器(模拟+贪心)

题面 [NOI2014] 随机数生成器 - 洛谷 题解 缝合题 第一部分,直接模拟题目操作生成二维数组即可,复杂度O(n*mQ) 第二部分,是一个比较经典的字典序贪心 首先肯定需要将最小的数放到路径上,这样可选的剩下的数就被限制在了最小数…

Redis 管道

问题由来:如何优化频繁命令往返造成的性能瓶颈? Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。 一个请求会遵循以下步骤: 1、客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果),并监听S…

Codeforces Round 883 (Div. 3) A~G

比赛链接:Dashboard - Codeforces Round 883 (Div. 3) - Codeforces 目录 A. Rudolph and Cut the Rope B. Rudolph and Tic-Tac-Toe C. Rudolf and the Another Competition D. Rudolph and Christmas Tree E. Rudolf and Snowflakes F. Rudolph and Mimic…

JavaWeb项目(包含SSM项目)部署到Linux云服务器

目录 一、云服务器环境部署 1、安装JDK 查看JDK的命令为: 安装JDK命令: 2、安装Tomcat 2.1 安装步骤 2.2 验证Tomcat是否启动成功 3、安装MySQL 二、部署 Web 项目到 Linux 2.1 在云服务器中数据库建库建表 2.2 修改部署项目连接数据库密码 …

Qt(Day2)

实现登录框中,当登录成功时,关闭登录界面,并跳转到其他界面:

Go实现在线词典翻译(三种翻译接口,结合sync)

火山翻译 首先介绍用火山翻译英译汉。 package mainimport ("bufio""bytes""encoding/json""fmt""io""log""net/http""os""strings""unicode" )type DictRequestHS st…

第四章:角色和菜单管理功能【基于Servlet+JSP的图书管理系统】

角色和菜单功能 一、角色功能 接下来我们可以完成角色管理的增删改查操作 1. Bean对象 创建sys_role对应的实体对象SysRole Data public class SysRole {private Integer id;private String name;private String notes;private Date createTime; }2. Dao层 现在我们就可以在D…

JVM(Java虚拟机)详解

目录 一、JVM内存区域划分 1. 什么是内存区域划分以及为啥要进行区域划分 2. JVM内存区域划分详解 3. 堆区详解: 4. 给一段代码,问某个变量是在那个区域上? 二、JVM类加载机制 1.类加载的过程 2. 类加载的时机 3. 双亲委派模型&#xff08…

下班前几分钟,我彻底玩懂了tmux

目录 1. tmux简介2. Session3. Window4. Pane5. 自定义tmux配置6. 在shell脚本中操纵tmuxReferences 1. tmux简介 tmux(terminal multiplexer)是一个非常强大的工具,主要有以下几点功能: 终端复用: tmux 使你能够在一…

Linux分布式应用 Zabbix监控配置[添加主机 自定义监控内容 邮件报警 自动发现/注册 代理服务器 高可用集群]

-------------------- 添加 zabbix 客户端主机 -------------------- 关闭防火墙 systemctl disable --now firewalld setenforce 0 hostnamectl set-hostname zbx-agent01 服务端和客户端都配置时间同步 yum install -y ntpdate ntpdate -u ntp.aliyun.com 服务端和客户端都设…

基于simulink跟踪火车站对象检测遗弃物体(附源码)

一、前言 此示例演示如何跟踪火车站的对象并确定哪些对象保持静止。公共场所的遗弃物品会引起当局的关注,因为它们可能会构成安全风险。算法(例如本例中使用的算法)可用于通过将他们的注意力引导到潜在的感兴趣区域来协助监控实时监控视频的…

二十五、传输层协议(上)

文章目录 一、再谈端口号(一)端口号定义(二)端口号范围划分1.一共有 2^16 个端口2.认识知名端口号(Well-Know Port Number)3.端口号和进程就是K-V关系4.netstat(1)示例1: n 拒绝显示别名&#x…

CentOS Linux上安装JDK11、MySQL8.0、Minio等软件(rpm脚本模式)

本地环境:Windows 10家庭版 16G内存 512G硬盘 软件:VMWare WorkStation 16.0 FinalShell 4.0.1 一、下载必要软件包 下载软件均选择x86架构64位!!!(可根据自己的电脑配置选择) CentOS Linu…