这篇文章主要介绍了 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 GCsetHead(node);
p.next = null;
// help GCfailed = 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;
/** * *for死循环测试 *
* * @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;
/** * *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)的区别】到此这篇关于 Java中for(; ; )和while(true)的区别的文章就介绍到这了,更多相关for(; ; )和while(true)的区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- java动态构建数据库复杂查询教程
- JAVA难点理解|(JAVA): 自定义枚举和enum枚举类型------详解。
- 计算机网络(王道考研)|3.4计算机网络(局域网基本概念和体系结构 以太网 )
- 大数据|前后端分离架构中的接口安全_如何立即确保您的应用架构安全(分离,配置和访问)
- 操作系统(王道考研)|2.7操作系统(读者—写者问题 哲学家进餐问题 管程 )
- 解决IDEA 2022 Translation 翻译文档失败: 未知错误的问题
- 我的碎碎念|真的无语,MSRA连国防七子及北邮学生都不招了
- Java毕业设计项目实战篇|Java项目:宿舍管理系统(java+SpringBoot+Thymeleaf+html+layui+mysql)
- Java毕业设计项目实战篇|Java项目:企业人事系统(java+SpringBoot+Vue+ElementUI+maven+mysql)