Java 9 Thread.onSpinWait for efficient waiting

When using a thread to run a task, it’s common to have the task wait for certain condition before it can continue. This is usually done by using busy-waiting with a volatile variable as the flag. This flag is set by another thread to stop the waiting. Before Java 9, we use an empty loop to wait for the condition. The new static method onSpinWait() of class Thread in Java 9 can make the waiting more efficient.

The code below shows an example of Thread.onSpinWait(). Classes NormalTask and SpinWaitTask both use the volatile boolean variable canStart as the flag. The flag is set to true using the method start(). The different of these two classes is that SpinWaitTask uses Thread.onSpinWait() in the loop. Here we use another thread to call the method start() after 3 seconds to stop the waiting. After running the code, you should see two Done! outputs in the console. It’s recommended to use Thread.onSpinWait to improve the performance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class ThreadOnSpinWait {
public static void main(final String[] args) throws InterruptedException {
final NormalTask task1 = new NormalTask();
final SpinWaitTask task2 = new SpinWaitTask();
final Thread thread1 = new Thread(task1);
thread1.start();
final Thread thread2 = new Thread(task2);
thread2.start();
new Thread(() -> {
try {
Thread.sleep(3000);
} catch (final InterruptedException e) {
e.printStackTrace();
} finally {
task1.start();
task2.start();
}
}).start();
thread1.join();
thread2.join();
}
private abstract static class Task implements Runnable {
volatile boolean canStart;
void start() {
this.canStart = true;
}
}
private static class NormalTask extends Task {
@Override
public void run() {
while (!this.canStart) {
}
System.out.println("Done!");
}
}
private static class SpinWaitTask extends Task {
@Override
public void run() {
while (!this.canStart) {
Thread.onSpinWait();
}
System.out.println("Done!");
}
}
}

Check out the book Exploring Java 9 for more new features in Java 9.

Comments