• Java 多线程 -- 指令重排(HappenBefore)


    指令重排是指:代码执行顺序和预期不一致。

    代码运行一般步骤为:
    1、从内存中获取指令解码
    2、计算值
    3、执行代码操作
    4、把结果写回内存

    而写回内存的操作比较耗时,CPU为了性能,可能不会等它完成,就进行对下一个指令解码计算。

    发生指令重排是CPU为了提高性能,但必须是对结果不影响的情况,比如:
    a =1; b =2; 先计算a 或者 b 对结果来说没有影响,就有肯能发送重排;而像 a = 5; b = a*3;这样的代码则不会发生重排。

    一把发生指令重排在单线程中基本没啥影响,当时在多线程中,同时操作一个数据,如果一个读,一个写,当写的线程还没写回时,另一个线程已经开始读取了,那么这个时候就会出现和预期不一致的结果。

    写一个可能生指令重排的代码:

    public class HappenBefore {
    
    	private static int a = 0;
    	private static boolean flag = false;
    	public static void main(String[] args) throws InterruptedException {
    		for (int i = 0; i < 10; i++) {
    			a = 0;
    			flag = false;
    			// 线程1 更改数据
    			Thread t1 = new Thread(() -> {
    				a = 1;
    				flag = true;
    			});
    			// 线程2 读取数据
    			Thread t2 = new Thread(() -> {
    				if (flag) {
    					a *= 1;
    				}
    				if (a == 0) {
    					System.out.println("指令重排了-->" + a);
    				}
    			});
    			t1.start();
    			t2.start();
    			// 合并线程,让更改数据线程先运行完
    			t1.join();
    			t2.join();
    		}
    		
    	}
    }
    

    运行以上代码:
    在这里插入图片描述
    我的电脑配的是最新的4代内存,运行10次,发生两次指令重排,如果用的是老一代的内存条,发生几率应该是会大一些。

    重视基础,才能走的更远。
  • 相关阅读:
    The executable was signed with invalid entitlements
    iOS7 文本转语音 AVSpeechSynthesizer
    The document "ViewController.xib" could not be opened. Could not read archive.
    UIPanGestureRecognizer
    UINavigationController
    IE6下面的css调试工具
    15款最好的网站音乐播放器
    ASP.NET常用加密解密方法
    ASP.NET根据IP获取省市地址
    强悍的CSS工具组合:Blueprint, Sass, Compass
  • 原文地址:https://www.cnblogs.com/xzlf/p/12681522.html
Copyright © 2020-2023  润新知