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

线程指令重排[通俗易懂]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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 关于我转生变成史莱姆这档事_kicker.de

    关于我转生变成史莱姆这档事_kicker.de1  请问什么所kworker进程 清理旧版本的软件缓存:  sudoapt-getautoclean这个进程是干什么的? 我的机器刚装11.04没次卡的时候top一下就发现kworker这个进程占用CPU很大,基本上都能到75%左右youmaytrytodisableallpowersavingcon

    2022年9月25日
    3
  • WPA2 KRACK Attacks 原文转载翻译[通俗易懂]

    WPA2 KRACK Attacks 原文转载翻译[通俗易懂]写在前面:博主水平有限,翻译中如果出现错误,还希望大家能够指正。原文链接:https://www.krackattacks.com/KeyReinstallationAttacks(krack)key重装攻击简介我们发现了关于WPA2的重大漏洞,WPA2是一个确保所有现代无线网络被保护的协议。当攻击者在受害者的一定范围内就可以利用这些漏洞来使用KRACK攻击。具体地说,攻

    2022年5月1日
    66
  • java 静态内部类 实例化_内部类及静态内部类的实例化「建议收藏」

    java 静态内部类 实例化_内部类及静态内部类的实例化「建议收藏」内部类的实例化如果内部类未声明为static,在实例化时首先需要new一个外部类的对象。并通过p.newInner()的方式new内部类,表明这个内部类指向该外部类。内部类的class类型为:Parent.Inner,而不是p.Inner,这个需要和new的方式区分开。publicclassTest{publicstaticvoidmain(String[]args){Pare…

    2022年10月9日
    1
  • charles是谁_shell sleep 毫秒

    charles是谁_shell sleep 毫秒前言Charles是收费软件,可以免费试用30天。试用期过后,未付费的用户仍然可以继续使用,但是每次使用时间不能超过30分钟,并且启动时将会有10秒种的延时。此时,我们只需网上找一个注册码即可解

    2022年7月30日
    8
  • QMap类说明[通俗易懂]

    QMap类说明[通俗易懂]QMap是一个模板类,提供了一个红黑树结构的查找字典。注:红黑树结构是自平衡二叉树QMap是一个QT常用的容器类,它存储键值队,并且可以很快的根据键查找值。QMap和QHash提供很类似的功能,他们的区别如下:1. QHash的查找性能更好;2.在遍历QHash时,里面是已经按字母排序好的,但是对于QMap,里面的东西都是按键分类的。3.QHash的键类型必须提供一

    2022年5月29日
    44
  • Java日志管理

    Java日志管理

    2021年6月8日
    102

发表回复

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

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