当前位置: 首页 > 知识库问答 >
问题:

java - Java单线程中指令重排序的可能性?

司徒捷
2024-04-16

Java指令重排序不影响单线程下执行结果。那么比如main线程里有
System.out.println("1");
System.out.println("2");
这两句话会重排导致输出21吗?这里似乎没有数据依赖?

共有2个答案

邵研
2024-04-16

不会,指令重排如果能达到这种效果那就不是重排是乱排了
指令重排影响的是多线程,单线程是没问题的

魏元白
2024-04-16

Java单线程中指令重排序不会导致输出结果的变化

在Java中,虽然编译器和处理器可能会对指令进行重排序,但这种重排序对于单线程程序来说是透明的,即它不会影响单线程程序的执行结果。编译器和处理器在重排序时,会遵守“as-if-serial”语义,即不管怎么重排序,单线程程序的执行结果不能被改变。

对于你给出的示例:

System.out.println("1");System.out.println("2");

即使编译器或处理器对这两条指令进行了重排序,输出结果仍然会是“1”和“2”,且顺序不会改变。这是因为这两条指令之间没有数据依赖关系,且Java内存模型保证了每个线程都有自己的本地内存,本地内存中的变量值不会被其他线程看到,除非通过显式的同步机制(如volatile、synchronized等)进行共享。

所以,在单线程中,你不需要担心指令重排序会影响程序的执行结果。但在多线程环境中,指令重排序可能会影响到程序的正确性,因此需要特别注意。

 类似资料:
  • 问题内容: 我正在阅读此博客文章。 作者正在谈论在多线程环境中打破in 。 有了: 变成: 作者说,我引用: “我在这里所做的是添加一个附加读取: 哈希的第二次读取,在返回之前 。听起来很奇怪,而且不太可能发生,第一次读取可以返回正确计算出的哈希值,内存模型允许第二次读取返回0!这是允许的,因为该模型允许对操作进行广泛的重新排序。第二次读取实际上可以在代码中移动,以便处理器在第一次读取之前进行处理

  • 问题内容: 在《 Java Concurrency InPractice》一书中,有几次告诉我们可以通过编译器,运行时JVM甚至处理器来重新排序程序的指令。因此,我们应该假定执行的程序不会以与源代码中指定的顺序完全相同的顺序执行其指令。 但是,上一章讨论的Java内存模型提供了一系列先 发生后 规则的清单,这些规则指示JVM保留哪些指令顺序。这些规则中的第一个是: “程序顺序规则。线程中的每个动作

  • 我试图在java中编写一个二进制线程树的前序遍历代码。我编写了下面的代码,它适用于一些示例,但我担心我忽略了一些边缘场景。 MORE INFO一个节点有两个引用左右分别指向节点的左右子节点。一个名为继任者的布尔字段根据无序遍历确定右指针指向子节点还是继任者(如果继任者==false:右指向子节点,否则指向无序遍历继任者) 如果有人能指出我逻辑上的缺陷,我将不胜感激... 任何帮助将不胜感激...:

  • 我正在尝试运行这个简单的类,并且对于每个cicle,我正在计算java进程线程的数量。 ps huH p pid wc-l。 对于每个cicle,线程数是availableProcessors()数的增加。 当ExecutorService在其他线程中运行时,garbace收集器似乎不会释放僵尸线程。 如果我创建了一个静态ExecutorService,它就不会发生

  • 问题内容: 如何为Java实现并发的quicksort或mergesort算法? 我们在16(虚拟)核的Mac上遇到问题,其中只有一个核(!)使用默认的Java排序算法工作,而且很好的机器没有得到充分利用是不好的。因此,我们编写了自己的代码(我编写了代码),并且确实取得了不错的提速(我编写了多线程快速排序,由于其分区特性,它可以很好地并行化,但我也可以编写合并排序)……但是我的实现只能扩展最多4个

  • 变量res的值应等于3。但是当我打开优化时,编译器错误地重新排列了指令,并且res包含一些垃圾。一些可能的重新排序示例: 这是编译器中的错误吗?还是不允许像这样访问结构数据成员? 编辑: 我刚刚意识到之前的代码实际上有效,抱歉。但这不起作用: 当编译时不知道变量i时,编译器会错误地重新排序指令。