In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
今天就跟大家聊聊有关Java中for(;;)和while(true)的区别是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
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 测试代码forpackage com.liziba.jsw;/** *
* for死循环测试 *
* * @Author: Liziba * @Date: 2021/6/21 11:36 */public class Test { private static void m1() { for (;;) { } } }
通过 javap -v Test.class查看生成的字节码(只截取关键部分)
2.2 测试代码whilepackage com.liziba.jsw;/** *
* while死循环测试 *
* * @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)的区别是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.