证明:Java代码在执行过程中,并不一定是从上到下,每句代码依次顺序执行的

2023-11-18

今天给大家带来一个毁三观的结论:Java代码在执行过程中,并不一定是从上到下,每句代码依次顺序执行的。这是不是很颠覆你的认知?

计算机在执行程序的时候,并不会严格按照代码来顺序执行。比如第一个指令,是从内存中读取一个数据,而第二个指令,是寄存器的某个值自增1。而如果这两个指令是毫无冲突的,没有任何关联性和依赖性,谁先谁后都不影响最终结果。那么 “机智” 的CPU就有可能调换执行的顺序。比如第一个指令先通过总线去寻址、取数据,这需要很长的时间,CPU没必要非要等到这个数据从内存中取到并赋值了之后,才执行第二个指令。CPU可以先请求总线去取数据,等数据的时候就执行第二个指令,将寄存器里面的某个值自增1。说不定自增完了数据还没取过来。然后假设第三条指令要对这个读取到的数据进行操作了,那么CPU就只能等了,等到数据读取到了,赋值了,再进行第三条指令。因为CPU是在是太快了,比内存的速度快两个数量级!

所以,我们知道了计算机在执行代码的时候,是会为了提高效率,根据上下文来进行指令重排的。但是这个听起来很玄乎,能不能证明呢?接下来的一个例子,就能够通过Java语言来证明,Java代码并不是一定按照代码的顺序,一句一句依次顺序执行的:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: LiYang
 * @Date: 2020/6/13 11:19
 * @Description: 证明Java代码执行中存在指令重排
 */
public class Disorder {

    //四个独立的类静态变量
    private static int a = 0;
    private static int b = 0;
    private static int x = 0;
    private static int y = 0;

    /**
     * 证明Java代码执行中存在指令重排的情况
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {

        //计数
        int count = 0;

        //线程池,固定两个线程
        ExecutorService executor = Executors.newFixedThreadPool(2);

        //一直执行,直到出现指令重排
        while (true) {

            //所有变量全部恢复初始值
            a = 0;
            b = 0;
            x = 0;
            y = 0;

            //计数加1
            count ++;

            //倒计时门栓,同步两个线程
            CountDownLatch latch = new CountDownLatch(2);

            //第一个线程
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    a = 1;
                    y = b;
                    latch.countDown();
                }
            });

            //第二个线程
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    b = 1;
                    x = a;
                    latch.countDown();
                }
            });

            //阻塞以上两个线程,等两个线程全部执行完毕后,继续执行下面的代码
            latch.await();

            //此时,上面的两个线程已经执行完毕。如果Java代码在执行过程中都是
            //一行一行的代码顺序执行的,那么上面两个线程无论是怎样的先后执行
            //顺序,a=1和b=1,这两句代码作为第一行代码,总有一句是最先执行的,
            //也就是说,到最后x或y肯定都不为0。如果到最后x和y都同时为0了,那
            //么根据反证法原理,Java代码在执行过程中,有可能并不绝对按照代码
            //顺序依次执行,当然也就发生了指令重排,Java代码执行中存在指令重排
            //的情况也就得到了证明

            //如果x和y都等于0了,就输出结果(如果Java代码真的按照顺序一句一句
            //执行的话,是绝对不可能出现x和y同时为0的)
            if (x == 0 && y == 0) {

                //指令重排输出语句
                String message = "第" + count + "次出现指令重排,x=" + x + ",y=" + y;

                //打印,证明完毕
                System.err.println(message);

                //结束程序
                System.exit(0);
            }
        }
    }

}

执行上面的代码,真的出现了x和y都为0的情况,通过反证法,也就证明了CPU在执行程序的过程中确实存在指令重排的现象,以Java为例,Java代码在执行过程中,并不一定是从上到下,每句代码依次顺序执行的(可能你的输出结果和我不一样,每次出现指令重排需要的时间不一定,有可能很快,也有可能要等很久):

95587次出现指令重排,x=0,y=0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

证明:Java代码在执行过程中,并不一定是从上到下,每句代码依次顺序执行的 的相关文章

  • IDEA中使用单元测试(Junit)Scanner控制台无法输入问题解决 2022.12.13

    步骤 Help Edit Custom VM options 在idea64 exe vmoptions文件中最后一行添加如下内容 Deditable java test console true 操作完成保存后一定要重启IDEA ps 通
  • StringUtils中 isNotEmpty 和isNotBlank的区别 以及StringUtil类的方法

    StringUtils方法的操作对象是java lang String类型的对象 是JDK提供的String类型操作方法的补充 并且是null安全的 即如果输入参数String为null则不会抛出NullPointerException 而
  • 详解万向锁

    最近在看高翔老师的slam十四讲时 对万向锁这个概念不是很清晰 于是从网上查了不少博客文档 最终明白了万向锁这个概念 在此记录一下 解释万向锁之前首先明白一下什么是欧拉角 什么是欧拉角 用一句话说 欧拉角就是物体绕坐标系三个坐标轴 x y
  • 使用VmWare安装黑苹果系统

    目录 1 介绍 2 破解安装VMware 3 unlocker解锁虚拟机 3 1 关闭VMware相关的进程 3 2 执行安装命令 4 VmWare创建虚拟机 5 下载并配置镜像以及虚拟机设置 5 1 修改镜像 5 2 修改虚拟机安装路径文
  • 如何把一张图片做成一个好看的电脑图标

    话不多说直奔主题 第一步 首先注意一下自己的桌面也就是想把什么东西的图标给换了 举个例子1 假如我们想换WPS图标 这时可以直接右击鼠标 gt 属性 gt 更换图标 然后找到目的图标位置更换就行了 2 假如我们想把一个 vbs程序的图标换了
  • 我的HTC G16 CHACHA A810e版手机如何解锁和一键root的

    之前用了很多方法 都无法将该手机进行解锁 unlock 后来 应用刷机精灵就解决了 里面对HTC的解锁进行了集成处理 无需登录HTC官网 使用该软件 刷了原厂系统 且把预装软件进行了卸载 非常方便 我的手机配置如下 刷机精灵为
  • 圆周率π的取值

    const double pi acos 1 0 头文件是
  • QImage的save函数保存的bmp图像无法打开

    最近在VS2010中用QT写一个小的程序 现在出现了一个问题实在不知道怎么解决 用save功能可以得到一个 bmp文件 但是不能读取这个图片的内容 而且每次截图图片的大小都是150K不变 整个调试过程都没有报错 相关代码如下 以上内容设置了
  • viso画图时如何让右侧显示设置形状格式栏

    选中一个形状 右击 点击设置形状格式 就出来了 我也琢磨了好久
  • 国内好的破解软件下载站

    MSDN https msdn itellyou cn 吾爱破解 https www 52pojie cn 奥学网 https 6so so 果核剥壳 http www ghboke com zd423 http www zdfans co
  • Oracle VirtualBox 6.1.18 安装扩展包

    VirtualBox安装扩展包 下载的Oracle VM VirtualBox Extension Pack包不是 vbox extpack格式的或扩展名的 怎么办 见下文插曲 下载扩展包 扩展名为vbox extpack 关闭虚拟机电脑
  • int , long , long long 的取值范围

    关于带符号与无符号类型 整型 int stort 和 long 都默认为带符号型 要获得无符号型则必须制定该类型为unsigned 比如unsigned long unsigned int类型可以简写为unsigned 也就是说 unsig
  • 图像质量评价指标及MATLAB程序

    指标名称 RMSE 针对一个volume的程序 M 230 行数 N 140 列数 P 11 切片数 计算RMSE volume P origin vector p P recon vector P recon MNP M N P nume
  • centos7 kvm 设置桥接网卡br0

    centos kvm 设置桥接网卡br0 一 关于kvm的操作 1 查看CPU是否支持VT egrep vmx svm color always proc cpuinfo 2 检查内核模块是否加载 lsmod grep kvm 3 查看Se
  • 安装HP LaserJet 1320n打印机驱动

    该打印机型号比较老了 不是网络打印机 只能通过并口或USB安装 由于笔记本不带并口 现在台式机基本都不带了 只能选择USB安装 折腾了好久 才找到正确的安装方法 特分享给大家 首先 就是找到正确的驱动 我的笔记本是win8 64bit的 所
  • windows中如何将收藏夹里的下载链接加入到开始

    windows中如何将收藏夹里的下载链接加入到开始 以windows 7为例 设置方法如下 1 右击工具栏 属性 2 开始菜单 自定义 下拉至下载 点中显示为链接 确定 3 可以看到 下载已经看到了
  • 如何判断三点共线

    如何判断三点共线 在二维坐标系中 给出三点A x1 y1 B x2 y2 C x3 y3 的坐标 判断三点共线的条件是 实质是判断有三个点组成的三角形面积为0 神爱世人 甚至将他的独生子 耶稣 赐给他们 叫一切信他的 不至灭亡 反得永生 圣
  • 证明:Java代码在执行过程中,并不一定是从上到下,每句代码依次顺序执行的

    今天给大家带来一个毁三观的结论 Java代码在执行过程中 并不一定是从上到下 每句代码依次顺序执行的 这是不是很颠覆你的认知 计算机在执行程序的时候 并不会严格按照代码来顺序执行 比如第一个指令 是从内存中读取一个数据 而第二个指令 是寄存
  • 如何将Visio绘制的图保存为300dpi的tif图片

    采用visio 2013绘图 用ctrl A全选绘制的图 开始 另存为 选择保存类型为tif Tif输出设置 分辨率设为300dpi 300dpi 验证一下图片分辨率 右击生成的tif文件 属性 详细信息
  • endnote插入的不是序号(而是大括号加上作者)的解决

    仅作为记录 大佬请跳过 之前用word通过endnote导入文献 都是可以的 在正文出现 1 的引用 但是博主新的word 需要修改参考文献 因此拟重新导入参考文献来修改 但发现导入的都是 Dou 2017 在正文中 文章目录 解决 参考

随机推荐

  • 【GD32F427开发板试用】多路ADC规则组同时采样 DMA进行传输数据 顺带开启FPU浮点运算

    本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动 更多开发板试用活动请关注极术社区网站 作者 Hello eQN7e7 前言 开启浮点运算 加快浮点类型数据计算 使用GD32F427V START开发板的ADC1采样四路电
  • 二极管连接的MOS管

    二极管连接的MOS管 求输出电阻时可以电压 电流负反馈
  • STM32CubeMX安装、使用、配置

    1 在官网下载应用 https www st com 并安装java环境所需软件jre 8u271 windows x64 exe 2 使用cube新建项目 打开file gt new prj 3 Pinout Configuration配
  • 985高校副教授晒年薪,网友:公积金顶我一个月工资了......

    教师的工资一直具有争议性 大家的认知两极分化 有人说教师收入特别高 也有人说教师收入堪堪够生活 不存在谁说假话 而是因为各地区教师薪资水平差异较大 学校属于事业单位 薪资受当地经济水平影响 而教师群体中收入最高的是大学老师 曾经就有一份统计
  • ubuntu21.10搭建ebpf环境,BCC和bpftrace

    1 安装虚拟机 虽说centos是生产环境中的标准系统 但是从个人学习角度还是推荐ubuntu 各种软件安装包都能方便地找到 操作界面时也很漂亮 之前一直在centos7 6上折腾 自己升级内核版本 自己安装各种高版本依赖 有一段时间被折磨
  • JavaScript i++与++i、=+与+=的区别

    i i i 先赋值再自增 i 先自增再赋值 都是表达式 i i 1 题目 var a 10 b 20 c 30 a a e a b c a 结果 77 表达式 A B B转化为数字 赋值给A 表达式 A B A A B let x 2 y
  • 会计计算机二级考试试题,计算机二级考试MS-Office考试题库--excle--有答案.docx

    请在 答题 菜单下选择 进入考生文件夹 命令 并按照题目要求完成下面的操作 注意 以下的文件必须保存在考生文件夹下 小蒋是一位中学教师 在教务处负责初一年级学生的成绩管理 由于学校地处偏远地区 缺乏必要的教学设施 只有一台配置不太高的PC可
  • qt界面之toolTip

    一般需要在按钮中加入toolTip的提示 可以如下所示 后续继续更新
  • java并发编程

    并发编程 1 java线程 1 1 创建线程 1 1 1 Thread 匿名内部类实现Thread线程 new Thread t1 Override public void run start 1 1 2 Runnable new Thre
  • MobaXterm 终端永久设置字体大小

    刚接触 MobaXterm 没多久 想设置下界面字体大小 结果翻了翻网上 一些人都在瞎扯 没一个好用的 自己解决之后 特写出来 找到顶部的Settings 进去之后 找到font settings 调整为你想要的字体大小 一般12 14 就
  • 听老人一句劝,别去外包,干了四年,废了....

    我是一个普通二本大学机械专业毕业 目前做IT行业的软件测试已经有4年多了 18年通过校招进入湖南某软件公司 干了接近4年的功能测试 今年年初 感觉自己不能够在这样下去了 长时间呆在一个舒适的环境会让一个人堕落 而我已经在一个企业干了四年的功
  • QT笔记——信号与槽

    Qt信号与槽机制通过connect 关联信号 QT4 1 槽函数必须有slots关键字 2 SIGNAL SLOT 将函数转为字符串 不进行错误检查 3 槽函数和信号一致 参数 返回值 没有返回值 sender 发送信号的对象 signal
  • C++中在类中重载输出运算符时遇到error: declaration of ‘class T‘的问题的解决

    一 问题代码及报错提示 include
  • 5 神经网络(PRML)

    之前我们讨论的模型是对于分类的回归模型 包含了线性组合的多个基础函数 但是他的应用范围有一定的限制 另外一个方法在于事先限定基础函数的个数并且使得他可自适应的 也就是说使得他的参数值在训练当中是可以发生变化的 其中最成功的模型是前向神经网络
  • 微信小程序开发(六)WXML 模板

    WXML模板
  • AttributeError: module ‘distutils‘ has no attribute ‘version‘ 解决方案

    问题描述 今天在执行时出现了题述错误 查阅了半天才找到解决方案 特此记录 LooseVersion distutils version LooseVersion 解决方案 将以上代码改写成 from distutils version im
  • JDBC基础

    JDBC是什么 用java语言操作关系型数据库的一套api JDBC是用来干什么的 用java语言来操作数据库 JDBC怎么写 1 加载驱动类Driver全限定名 包 类名 2 获取连接 getConnection url username
  • maven.plugins.enforcer.BannedDependences 异常解决方案

    maven plugins enforcer BannedDependences 异常解决方案 简介 maven enforce plugin是一个规范maven构建环境的插件 例如 Maven版本 JDK版本和OS系列以及更多内置规则和用
  • 图的基本操作(无向图)

    图的定义 图 Graph 在是一种较线性表和树更为复杂的数据结构 在线性表中 数据元素之间是被串起来的 只有线性关系 每个数据元素只有一个直接前驱和一个直接后继 在树形结构中 数据元素之间有着很明显的层次关系 并且每一层的数据元素可能和下一
  • 证明:Java代码在执行过程中,并不一定是从上到下,每句代码依次顺序执行的

    今天给大家带来一个毁三观的结论 Java代码在执行过程中 并不一定是从上到下 每句代码依次顺序执行的 这是不是很颠覆你的认知 计算机在执行程序的时候 并不会严格按照代码来顺序执行 比如第一个指令 是从内存中读取一个数据 而第二个指令 是寄存