共计 1959 个字符,预计需要花费 5 分钟才能阅读完成。
这篇文章次要介绍了 Java 中 for(;;)和 while(true)的区别,文章围绕 for(;;)和 while(true)的相干自来哦开展具体内容,须要的小伙伴能够参考一下,心愿对大家有所帮忙
目录
1、问题起源
2、比拟
2.1 测试代码 for
2.2 测试代码 while
3、论断
1、问题起源
在浏览 Java 的 JDK 源码时,发现大部分写源码的大佬多采纳 for(;;)的形式来死循环,比如说 AQS(AbstractQueuedSynchronizer)中大量应用的自旋的形式获取共享状态。
/**
* 通过“死循环”的形式来正确的增加节点
*/
private Node enq(final Node node) {
// 一直循环,直至 CAS 插入节点胜利
for (;;) {
Node t = tail;
if (t == null) {
// 当尾节点为 null,此时须要初始化头节点和尾节点
if (compareAndSetHead(new Node()))
tail = head;
} else {
// 插入节点前驱节点指向原先尾节点
node.prev = t;
// CAS 插入至同步队列的尾节点
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
/**
*“死循环”获取同步状态,并且以后仅当前驱节点是头节点是才可能尝试获取同步状态
*/
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
// 一直循环
for (;;) {
// 获取以后节点的前驱节点,如果前驱节点为 null 将会抛出空指针异样
final Node p = node.predecessor();
// 如果以后节点的前驱节点是头节点,尝试获取同步状态
if (p == head && tryAcquire(arg)) {
// 设置以后节点为头节点,并且将节点线程和节点的前驱节点置为 null,help GC
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
// 如果不符合条件,则判断以后节点前驱节点的 waitStatus 状态来决定是否须要挂起 LockSupport.park(this);
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
// 失败则勾销
if (failed)
cancelAcquire(node);
}
}
2、比拟
Java 代码在编译后都会装换为虚拟机能够辨认的字节码,咱们通过编译器对两者生成的字节码从原理是来察看两者的区别
2.1 测试代码 for
package com.liziba.jsw;
/**
* <p>
* for 死循环测试
* </p>
*
* @Author: Liziba
* @Date: 2021/6/21 11:36
*/
public class Test {private static void m1() {for (;;) {}}
}
通过 javap -v Test.class 查看生成的字节码(只截取要害局部)
2.2 测试代码 while
package com.liziba.jsw;
/**
* <p>
* while 死循环测试
* </p>
*
* @Author: Liziba
* @Date: 2021/6/21 11:36
*/
public class Test {private static void m2() {while (true){}}
}
通过 javap -v Test.class 查看生成的字节码(只截取要害局部)
3、论断
for 死循环和 while 死循环编译后的字节码(编译器是能够做优化的),齐全截然不同,所以两者在应用过程中,其实是没有任何区别。看到这里是不是有点怄气,然而又想问问什么源码那些大佬写代码基本上不必 while(true),我想次要起因还是晚期 C 语言中 for(;;) 循环和 while(1)编译生成的字节码不一样,for(;;)生成的字节码显著更加少,肯定水平上能节俭一些内存空间。所以很多 java 大佬,也是精通各种其余语言的,因而写法习惯也就连续下来了吧。再者,我在查阅材料的时候也看到有笔者验证晚期的 Java 编译器对 for 死循环编译生成的字节码也是少于 while 死循环编译后生成的字节码,可能随着编译器优化能力一直的加强,当初这两者在目前宽泛应用的编译器中曾经没有什么区别了。
到此这篇对于 Java 中 for(;;)和 while(true)的区别的文章就介绍到这了, 更多相干 for(;;)和 while(true)的区别内容请搜寻脚本之家以前的文章或持续浏览上面的相干文章心愿大家当前多多反对脚本之家!