我们经常会在线程里做一个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() {}
。。。。。。。。。。。。。。。
原来如此—— ——~~!