中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中for(;;)和while(true)的區別是什么

發布時間:2021-11-25 13:13:14 來源:億速云 閱讀:175 作者:柒染 欄目:開發技術

今天就跟大家聊聊有關Java中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查看生成的字節碼(只截取關鍵部分)

    Java中for(;;)和while(true)的區別是什么

    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)的區別是什么有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    虞城县| 明溪县| 辛集市| 子长县| 游戏| 鄂州市| 天镇县| 沐川县| 甘孜县| 云阳县| 翼城县| 洛宁县| 马关县| 鄂托克旗| 崇州市| 铁岭县| 宁远县| 祁连县| 舒城县| 周至县| 綦江县| 永平县| 天全县| 和政县| 西畴县| 常宁市| 胶州市| 同江市| 古交市| 九龙坡区| 桃源县| 顺义区| 墨脱县| 佛冈县| 漳浦县| 江源县| 伽师县| 弋阳县| 荃湾区| 海南省| 巴东县|