Java中for(;;)和while(true)的区别

 更新时间:2021年11月25日 10:50:30   作者:海拥  
这篇文章主要介绍了 Java中for(;;)和while(true)的区别,文章围绕for(;;)和while(true)的相关自来哦展开详细内容,需要的小伙伴可以参考一下,希望对大家有所帮助

1、问题来源

在阅读JavaJDK源码时,发现大部分写源码的大佬多采用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死循环编译后生成的字节码,可能随着编译器优化能力不断的增强,现在这两者在目前广泛使用的编译器中已经没有什么区别了。

到此这篇关于 Javafor(;;)while(true)的区别的文章就介绍到这了,更多相关for(;;)while(true)的区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何用Java 几分钟处理完 30 亿个数据(项目难题)

    如何用Java 几分钟处理完 30 亿个数据(项目难题)

    现有一个 10G 文件的数据,里面包含了 18-70 之间的整数,分别表示 18-70 岁的人群数量统计,今天小编通过本文给大家讲解如何用Java 几分钟处理完 30 亿个数据,这个问题一直以来是项目难题,今天通过本文给大家详细介绍下,感兴趣的朋友一起看看吧
    2022-07-07
  • java实现在pdf模板的指定位置插入图片

    java实现在pdf模板的指定位置插入图片

    这篇文章主要为大家详细介绍了java如何实现在pdf模板的指定位置插入图片,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • 浅谈Java自定义注解相关知识

    浅谈Java自定义注解相关知识

    今天带大家来学习Java注解的相关知识,文中对自定义注解作了非常详细的介绍,对正在学习Java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • IDEA2023版本创建Spring项目只能勾选17和21却无法使用Java8的完美解决方案

    IDEA2023版本创建Spring项目只能勾选17和21却无法使用Java8的完美解决方案

    想创建一个springboot的项目,本地安装的是1.8,但是在使用Spring Initializr创建项目时,发现版本只有17和21,这篇文章主要介绍了IDEA2023版本创建Sping项目只能勾选17和21,却无法使用Java8的解决方法,需要的朋友可以参考下
    2023-12-12
  • IDEA部署Tomcat的超详细图文教程

    IDEA部署Tomcat的超详细图文教程

    最近迫于无奈从我哪破旧的Eclipse转换到了IDEA,然后就是超多的不习惯,下面这篇文章主要给大家介绍了关于IDEA部署Tomcat的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • Windows7下的Java运行环境搭建过程图解

    Windows7下的Java运行环境搭建过程图解

    这篇文章主要介绍了Windows7下的Java运行环境搭建过程图解,需要的朋友可以参考下
    2014-04-04
  • Java @Value(

    Java @Value("${xxx}")取properties时中文乱码的解决

    这篇文章主要介绍了Java @Value("${xxx}")取properties时中文乱码的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Mybatis 中的一对一,一对多,多对多的配置原则示例代码

    Mybatis 中的一对一,一对多,多对多的配置原则示例代码

    这篇文章主要介绍了 Mybatis 中的一对一,一对多,多对多的配置原则示例代码,需要的朋友可以参考下
    2017-03-03
  • iReport简单使用方法图文教程

    iReport简单使用方法图文教程

    iReport是一个能够创建复杂报表的开源项目,它100%使用Java语言编写,是目前全球最为流行的开源报表设计器,由于它丰富的图形界面,你能够很快的创建出任何一种你想要的报表
    2021-10-10
  • Spring Boot ActiveMQ连接池配置过程解析

    Spring Boot ActiveMQ连接池配置过程解析

    这篇文章主要介绍了Spring Boot ActiveMQ连接池配置过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论