线程指令重排[通俗易懂]

线程指令重排[通俗易懂]1、指令重排JVM为优化执行效率对线程内的执行顺序进行重排,对单线程来说执行指令重排并不会影响程序从上到下执行的代码逻辑。但是在多线程的情况下,则可能会出现问题。2、指令重排原则程序顺序原则:一个线程内保证语义的串行性volatile规则:volatile变量的写,先发生于读锁规则:解锁(unlock)必然发生在随后的加锁(lock)前传递性:A先于B,B先于C那么A必然先于C线程的start方…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

1、指令重排

JVM为优化执行效率对线程内的执行顺序进行重排,对单线程来说执行指令重排并不会影响程序从上到下执行的代码逻辑。但是在多线程的情况下,则可能会出现问题。

2、指令重排原则

程序顺序原则:一个线程内保证语义的串行性

volatile规则:volatile变量的写,先发生于读

锁规则:解锁(unlock)必然发生在随后的加锁(lock)前

传递性:A先于B,B先于C 那么A必然先于C

线程的start方法先于它的每一个动作

线程的所有操作先于线程的终结(Thread.join())

线程的中断(interrupt())先于被中断线程的代码

对象的构造函数执行结束先于finalize()方法

3、代码示例(实际演示中没有演示出效果快哭了

package com.thread.study;

public class OrderExample {
	
	int a = 0;
	boolean  flag = false;
	
	public void write(){
		a = 1;
		flag = true;
	}
	
	public void read(){
		if(flag){
			int i = a + 1;
			System.err.println("i="+i+"a="+a+"flag="+flag);
		}
	}
	
	public static void main(String[] args){
		
		OrderExample order = new OrderExample();
		
		//A线程执行write方法,但是无法保证 a=1执行在前,flag = true执行在后
		Thread threadA = new Thread(new Runnable(){
			@Override
			public void run() {
				order.write();
		}});
		//线程 B执行read方法
		Thread threadB = new Thread(new Runnable(){
			@Override
			public void run() {
				order.read();
		}});
		threadA.start();
		threadB.start();
		
	}
}

4、避免指令重排

指令重排是编译器的一种优化手段,但是在多线程中可能会影响到代码逻辑。如何避免指令重排可以通过同步的方式(性能问题)

package com.thread.study;

public class OrderExample {
	
	int a = 0;
	boolean  flag = false;
	
	public synchronized void write(){
		a = 1;
		flag = true;
	}
	
	public synchronized void read(){
		if(flag){
			int i = a + 1;
			System.err.println("i="+i+"a="+a+"flag="+flag);
		}
	}
	
	public static void main(String[] args){
		
		OrderExample order = new OrderExample();
		
		//A线程执行write方法,但是无法保证 a=1执行在前,flag = true执行在后
		Thread threadA = new Thread(new Runnable(){
			@Override
			public void run() {
				order.write();
		}});
		//线程 B执行read方法
		Thread threadB = new Thread(new Runnable(){
			@Override
			public void run() {
				order.read();
		}});
		threadA.start();
		threadB.start();
		
	}
}

网上看到指令重排会对懒汉-单例模式有影响,后续分析。。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180658.html原文链接:https://javaforall.net

(0)
上一篇 2022年10月18日 下午1:16
下一篇 2022年10月18日 下午1:36


相关推荐

  • gcc编译c++文件

    gcc编译c++文件gcc 是编译 c 语言的 默认情况下 如果直接编译 c 程序 会报错 root serverdemo2 lshello cpp root serverdemo2 cathello cpp nbsp include lt iostream gt usingnamespa intmain nbsp cout lt lt hello c lt lt end

    2026年3月17日
    1
  • Java循环语句

    Java循环语句Java基础:循环语句,利用随机数实现验证码

    2022年7月7日
    26
  • css如何设置背景图片?background属性添加背景图片

    css如何设置背景图片?background属性添加背景图片在前端开发过程中 为了页面的美观 往往都会给 html 页面添加背景图片 那么如何利用 css 设置 html 中用图片做背景 本章就给大家介绍 css 怎样设置背景图片 有一定的参考价值 有需要的朋友可以参考一下 希望对你有所帮助 更多相关视频 0 基础前端利用 HTML CSS 制作你喜欢的暗黑破坏神网页开发 BV1C54y1X7ro 前端发展简史 功能以及未来趋势 你值得观看 BV1w5411s7e4 给想学编程又无从下手的小白一些建议 BV1Zf4y117ji HTML CSS 实现妙笔千山

    2026年3月18日
    2
  • java mvel_什么是MVEL?

    java mvel_什么是MVEL?1 MVEL 是啥 它能做啥 简单来说是一种强大的表达式解析器 我们可以自己写一些表达式 交给 mvel 进行解析计算 得到这个表达式计算的值 玩概念 我不懂 还是举个例子靠谱 比如我们要进行一个加法运算 在 java 中我们这样写 intres 1 1 2 若我用 mvel 则这样写 Objectres MVEL eval 1 1 2 是不是很吃惊 1 1 就是一个表达

    2026年3月18日
    2
  • AI周报:DeepSeek-V4将至迎战腾讯混元,字节Seedance 2.0因版权暂停全球发布

    AI周报:DeepSeek-V4将至迎战腾讯混元,字节Seedance 2.0因版权暂停全球发布

    2026年3月16日
    2
  • 定点数和浮点数的表示

    定点数和浮点数的表示计算机中常用的数据表示格式有两种 一种是定点格式 二是浮点格式 定点数和浮点数的意思是 小数点的位置是固定的还是浮动的 一般来说定点格式能表示的数值范围有限 单要求处理的硬件简单一些 浮点格式能表示的数的范围很大 但要求处理的硬件比较复杂一些 定点数 所谓定点格式 是指小数点位置是固定不变的 定点数的表示方式有两种 第一种是 定点小数用于表示纯小数 小数点固定在符号位和数值位之间第二种是 定点整数用于表示纯整数 小数点固定数值后面浮点数 小数点的位置由阶码规定 因此是浮动的 用来

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号