1.jvm内存模型

硬件内存模型

处理器--》高速缓存--》缓存一致性协议--》主存

java内存模型

线程《--》工作内存《--》save和load 《---》主存

java内存间的交互操作

(1)lock(锁定):作用于主内存的变量,把一个变量标记为一条线程独占状态

(2)unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线 程锁定

(3)read(读取):作用于主内存的变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作 使用

(4)load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中

(5)use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎

(6)assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量

(7)store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作

(8)write(写入):作用于主内存的变量,它把store操作从工作内存中的一个变量的值传送到主内存的变量中

上面8中操作必须满足以下规则

1、不允许read和load、store和write操作之一单独出现,即不允许一个变量从主内存读取了但工作内存不接

受,或者从工作内存发起回写了但主内存不接受的情况出现。

2、不允许一个线程丢弃它的最近的assign操作,即变量在工作内存中改变了之后必须把该变化同步回主内存。

3、不允许一个线程无原因地(没有发生过任何assign操作)把数据从线程的工作内存同步回主内存。

4、一个新的变量只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量,换句话说,就是对一个变量实施use、store操作之前,必须先执行过了assign和load操作。

5、一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。

6、如果对一个变量执行lock操作,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值。

7、如果一个变量事先没有被lock操作锁定,那就不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定住的变量。

8、对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store、write操作)。

2.先行发生原则 happens-before

判断数据是有有竞争、线程是否安全的主要依据

1.程序次序规则:同一个线程内,按照代码出现的顺序,前面的代码先行于后面的代码,准确的说是控制流顺

序,因为要考虑到分支和循环结构。

  1. 管程锁定规则:一个unlock操作先行发生于后面(时间上)对同一个锁的lock操作。

  2. volatile变量规则:对一个volatile变量的写操作先行发生于后面(时间上)对这个变量的读操作

  3. 线程启动规则:Thread的start( )方法先行发生于这个线程的每一个操作。

  4. 线程终止规则:线程的所有操作都先行于此线程的终止检测。可以通过Thread.join( )方法结束、

    Thread.isAlive( )的返回值等手段检测线程的终止。

  5. 线程中断规则:对线程interrupt( )方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可

    以通过Thread.interrupt( )方法检测线程是否中断

  6. 对象终结规则:一个对象的初始化完成先行于发生它的finalize()方法的开始。

  7. 传递性:如果操作A先行于操作B,操作B先行于操作C,那么操作A先行于操作C。

    为什么要有该原则?
     无论jvm或者cpu,都希望程序运行的更快。如果两个操作不在上面罗列出来的规则里面,那么就可以对他们进行任意的重排序。
    时间先后顺序与先行发生的顺序之间基本没有太大的关系。

3.指令重排序

什么是指令重排序?

重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。

数据依赖性

编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执

行顺序。(仅针对单个处理器中执行的指令序列和单个线程中执行的操作,不同处理器之间和不同线程之间的

数据依赖性不被编译器和处理器考虑。)

两操作访问同一个变量,其两个操作中有至少一个写操作,此时就存在依赖性

写后读 a=0 b=a

读后写 a=b b=1

写后写 a=1 a=2 a=1,b=1

写后读 a=0 b=a 正确b=0 错误b=1

as-if-serial原则

不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。

x=0,y=1

x=1, y=0

x=1, y=1

x=0, y=0

public class Demo2 {

    static  int x = 0, y = 0, a = 0, b = 0;

    public static void main(String[] args) throws InterruptedException {

        int i = 0;
boolean flag = true;
while (flag) {
i++; Thread thread = new Thread(() -> {
a = 1;
x = b;
}); Thread thread1 = new Thread(() -> {
b = 1;
y = a;
}); thread.start();
thread1.start();
thread.join();
thread.join(); System.out.println(
"第" + i + "次的值:" + "x=" + x + " y=" + y
); if (x == 0 && y == 0) {
flag = false;
} else { x = 0;
y = 0;
a = 0;
b = 0;
} } } }

JVM与并发的更多相关文章

  1. 阿里Java架构师面试高频300题:集合+JVM+Redis+并发+算法+框架等

    前言 在过2个月即将进入9月了,然而面对今年的大环境而言,跳槽成功的难度比往年高了很多,很明显的感受就是:对于今年的java开发朋友跳槽面试,无论一面还是二面,都开始考验一个Java程序员的技术功底和 ...

  2. 《Java程序性能优化》学习笔记 JVM和并发优化

    第四章 并行程序优化 1.非阻塞同步避免了基于锁的同步的缺陷,无锁算法没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销.CAS算法:包含3个参数CAS(v,e,n).V表示要更新的变量,E表示 ...

  3. JVM并发机制的探讨——内存模型、内存可见性和指令重排序

    并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...

  4. JVM原理和优化

    JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境. 1.创建JVM装载环境和配置 2.装载JVM.dll 3.初始化JVM.dll并挂界 ...

  5. JVM实用参数(七)CMS收集器

    HotSpot JVM的并发标记清理收集器(CMS收集器)的主要目标就是:低应用停顿时间.该目标对于大多数交互式应用很重要,比如web应用.在我们看一下有关JVM的参数之前,让我们简要回顾CMS收集器 ...

  6. jvm 原理和优化

    在csdn 上看到的,觉得很好,收藏了: 原博文地址: 濤子 http://blog.csdn.net/ning109314/article/details/10411495/ JVM工作原理和特点主 ...

  7. Java系列笔记(6) - 并发(上)

    目录 1,基本概念 2,volatile 3,atom 4,ThreadLocal 5,CountDownLatch和CyclicBarrier 6,信号量 7,Condition 8,Exchang ...

  8. JVM知识学习与巩固

    JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. 我们运行和调 ...

  9. jvm参数优化

    一.HotSpot JVM 提供了三类参数 现在的JVM运行Java程序(和其它的兼容性语言)时在高效性和稳定性方面做的非常出色.例如:自适应内存管理.垃圾收集.及时编译.动态类加载.锁优化等.虽然有 ...

随机推荐

  1. python url码转换 chr()码

    爬虫生成带搜索词语的网址 1.字符串转为url编码 import urllib poet_name = "李白" url_code_name = urllib.quote(poet ...

  2. 怎么让input默认为0

    <span class="item_title">供应商定金</span> <div class="flex-fill flex" ...

  3. js逆向分析之acorn和escodegen的使用

    替换之前的d形如 d("77696669") 执行代码 const fs = require('fs'); const acorn = require('acorn'); cons ...

  4. [BUAA软工]Alpha阶段项目展示

    [冰多多]Alpha项目展示 冰多多项目: 语音coding 助手, alpha阶段目标: 语音辅助输入 一. 团队成员的简介和个人博客地址 成员 角色 个人博客地址 卓培锦 PM, 后端开发 htt ...

  5. Why you need to understand garbage collection

    Why you need to understand garbage collection I’ve been interviewing lots of C# developers recently, ...

  6. html5 input number类型使用整理

      一.  html5 input中的数字number类型, 只能输入整数,如果要输入浮点数呢,可以通过max.min和step去定义. type="number" 数字类型 mi ...

  7. 阿里巴巴Druid数据源组件

    目前常用的数据源主要有c3p0.dbcp.proxool.druid,先来说说他们Spring 推荐使用dbcp:Hibernate 推荐使用c3p0和proxool1. DBCP:apacheDBC ...

  8. nohup: 无法运行命令"java": 没有那个文件或目录

    问题 在一个Linux服务器上有shell 脚本如下: nohup java -jar test.jar >> ./nohup.out 2>&1 & 直接执行脚本 s ...

  9. jQuery 取值操作

    模板使用: https://startbootstrap.com/themes/sb-admin-2/ 使用的 bootstrap 模块 ,上面的这个网站可以下载 select 取值 <sele ...

  10. fiddler抓包详解

    image.png 前言 fiddler是一个很好的抓包工具,默认是抓http请求的,对于pc上的https请求,会提示网页不安全,这时候需要在浏览器上安装证书. 一.网页不安全 1.用fiddler ...