您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Java中for(;;)和while(true)的區別是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
在閱讀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); } }
Java
代碼在編譯后都會裝換為虛擬機可以識別的字節碼,我們通過編譯器對兩者生成的字節碼從原理是來觀察兩者的區別
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
查看生成的字節碼(只截取關鍵部分)
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
查看生成的字節碼(只截取關鍵部分)
for
死循環和while
死循環編譯后的字節碼(編譯器是可以做優化的),完全一模一樣,所以兩者在使用過程中,其實是沒有任何區別。看到這里是不是有點生氣,但是又想問問什么源碼那些大佬寫代碼基本上不用while(true)
,我想主要原因還是早期C語言中for(;;)
循環和while(1)
編譯生成的字節碼不一樣,for(;;)
生成的字節碼明顯更加少,一定程度上能節省一些內存空間。所以很多java
大佬,也是精通各種其他語言的,因此寫法習慣也就延續下來了吧。再者,我在查閱資料的時候也看到有筆者驗證早期的Java
編譯器對for
死循環編譯生成的字節碼也是少于while
死循環編譯后生成的字節碼,可能隨著編譯器優化能力不斷的增強,現在這兩者在目前廣泛使用的編譯器中已經沒有什么區別了。
看完上述內容,你們對Java中for(;;)和while(true)的區別是什么有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。