1. 程式人生 > >你知道for(;;) vs. while(true)那個更快嗎?

你知道for(;;) vs. while(true)那個更快嗎?

來來來, for(;;) vs. while(true) 有什麼區別?從java的語義上來說,他們是一模一樣的。為何怎麼說?

開始我們先測試for(;;)

package com.tony.test;
import org.junit.Test;
/**
 * 測試迴圈
 *
 * @author tony
 * @create 2019-12-26 10:43
 **/
public class LoopTest {
    @Test
    public void testFor() {
        for (; ; ) {
            System.out.println("Tony Teacher test for");
        }
    }
}

輸出的位元組碼如下

// class version 51.0 (51)
// access flags 0x21
public class com/tony/test/LoopTest {
  // compiled from: LoopTest.java
  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 11 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public testFor()V
  @Lorg/junit/Test;()
   L0
    LINENUMBER 16 L0
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "Tony Teacher test for"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    GOTO L0
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

我們再測試while (true)

package com.tony.test;
import org.junit.Test;
/**
 * 測試迴圈
 *
 * @author tony
 * @create 2019-12-26 10:43
 **/
public class LoopTest {
    @Test
    public void testWhile() {
        while (true) {
            System.out.println("Tony Teacher test while");
        }
    }
}

輸出的位元組碼如下

// class version 51.0 (51)
// access flags 0x21
public class com/tony/test/LoopTest {
  // compiled from: LoopTest.java
  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 11 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public testFor()V
  @Lorg/junit/Test;()
   L0
    LINENUMBER 16 L0
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "Tony Teacher test while"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    GOTO L0
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

引用網上的一段話

Semantically, they're completely equivalent. It's a matter of taste, but I think while(true) looks cleaner, and is easier to read and understand at first glance. In Java neither of them causes compiler warnings.
At the bytecode level, it might depend on the compiler and the level of optimizations, but in principle the code emitted should be the same.

這個兩種寫法都是可以的,取決於編譯器和優化的級別,原則上是一模一樣的。

下次面試官再問你這種問題,你就可以懟回去。通過ASM,檢視byteCode碼。這兩貨是一模一樣的。對我而言,我喜歡用for(;;),感覺for裡面肯定會有退出迴圈的情況,

但是while(true),咋一看會感覺一直會迴圈下去。
只是看個人喜歡,你喜歡用那種寫法呢?

再講講 while(true)

當你使用一個空迴圈的時候,你觀察一下不一會你的CPU使用率就達到100%,如何不讓CPU使用達到100%?此刻如果面試官問你,你該怎麼回答?
Thread.sleep , 對的sleep方法。因為while 會消耗掉所有可以的計算資源。你此刻如果生成dump檔案,你會發現jvm垃圾回收時間是很頻繁的。

while (true)
{
    try
    {
        Thread.sleep(500);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

500毫秒毫秒迴圈一次,你可別小看這500毫秒。你可知道一毫秒cpu可以做很多的事情了。此刻你執行緒等待,可以讓cpu去幹其他的事情了。

你猜對了答案嗎?其實這些問題,我們平常看原始碼都看到過。但是你有沒有去總結為什麼這麼寫?知其然更知其所以然。IT這條路是漫長、孤獨且枯燥,需要靜下心來好好琢磨學習。堅持下來,你一定會享受到編碼帶來的快樂和財富。

掃一掃關注下,更多分享等著你。

『託尼老師』從事網際網路研發工作10+年,經歷過大大小小公司的洗禮。定期分享技術的文章,希望各位同僚關注我,我們一起探討技術人生