While learning Java 9 features I came across a new method of Thread
class, called onSpinWait. As per javadocs, this method is used for this:
It's the same (and probably compiles to) as the x86 opcode PAUSE
and equivalent the Win32 macro YieldProcessor
, GCC's __mm_pause()
and the C# method Thread.SpinWait
It's a very weakened form of yielding: it tells your CPU that you are in a loop that may burn many CPU-cycles waiting for something to happen (busy-waiting).
This way, The CPU can assign more resources to other threads, without actually loading the OS scheduler and dequeuing a ready-to-run thread (which may be expensive).
A common use for that is spin-locking, when you know the contention on a shared memory is very infrequent or finishes very quickly, a spinlock may preform better than an ordinary lock.
Pseudo code for such can look like:
int state = 0; //1 - locked, 0 - unlocked
routine lock:
while state.cas(new_value=1, wanted_value=0) == false //if state is 0 (unlocked), store 1 (locked) and return true, otherwise just return false.
yield
routine unlock:
atomic_store(state,0)
yield
can be implemented with Thread.onSpinWait()
, hinting that while trying to lock the lock, the CPU can give more resources to other threads.
This technique of yielding is extremely common and popular when implementing a lock-free algorithm, since most of them depend on busy-waiting (which is implemented almost always as an atomic compare-and-swap loop). this has every real-world use you can imagine.