JDK9新API:Thread.onSpinWait()

柴月和岐月發表於2017-09-28

 

我們經常會線上程裡做一個while(boolean){}的操作,來進行條件等待,比如:

 

        new Thread() {
            @Override
            public void run() {
                while (isCall) {//女神怎麼還沒回我訊息啊
                    try {
                        sleep(1000);//隔一秒看下手機
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

但現在JDK9裡面給我們提供了一個新的API專門代替上面的//隔一秒看下手機,不過得注意這個得寫在你的迴圈體裡面(雖然寫在外面也不會錯啦,但是並沒有什麼用)

 

以下是例子:

 

public class HelloJDK9 {
    volatile boolean eventNotificationNotReceived = true;

    public void setEventNotificationNotReceived(boolean eventNotificationNotReceived) {
        this.eventNotificationNotReceived = eventNotificationNotReceived;
    }

    public static void main(String[] args) {
        HelloJDK9 helloJDK9 = new HelloJDK9();
        new Thread() {
            @Override
            public void run() {
                System.out.println("執行緒一開始等待執行緒二的指令");

                while (helloJDK9.eventNotificationNotReceived) {
                    Thread.onSpinWait();
                }
                System.out.println("執行緒一收到執行緒二的指令");
            }
        };
        new Thread() {
            @Override
            public void run() {
                try {
                    System.out.println("執行緒二等待1秒");
                    sleep(1000);
                    helloJDK9.setEventNotificationNotReceived(false);
                    System.out.println("執行緒二發出指令");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    }
}

 

輸出結果為:

執行緒一開始等待執行緒二的指令
執行緒二等待1秒
執行緒二發出指令
執行緒一收到執行緒二的指令

雖說效果等同於上面的“sleep(1000);//隔一秒看下手機”,但是內部是不是真的是這樣呢?我們加幾句程式碼試驗下

 

while (helloJDK9.eventNotificationNotReceived) {
                    long time=System.currentTimeMillis();
                    Thread.onSpinWait();
                    System.out.println(System.currentTimeMillis()-time);
                }

輸出結果為:

 

執行緒一開始等待執行緒二的指令
執行緒二等待1秒

0

....N個0

0
執行緒二發出指令
執行緒一收到執行緒二的指令
 

是0哎,真的是0ms嗎?那麼不測時間了,測下執行了多少次吧

 

                int num=0;
                while (helloJDK9.eventNotificationNotReceived) {
                    num++;
                    Thread.onSpinWait();
                }

輸出結果為:

 

執行緒一開始等待執行緒二的指令
執行緒二等待1秒
執行緒二發出指令
執行緒一收到執行緒二的指令,num=102297173

好吧,還真可能是0ms。好吧,看下原始碼

 

    @HotSpotIntrinsicCandidate
    public static void onSpinWait() {}

。。。。。。。。。。。。。。。

 

原來如此—— ——~~!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章