这篇文章次要介绍了 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)的区别内容请搜寻脚本之家以前的文章或持续浏览上面的相干文章心愿大家当前多多反对脚本之家!