If we are in a situation with two running threads on a machine with two processors and we call Thread.yield()
within one of those threads, does it stand to reason that nothing will happen (the scheduler will essentially ignore the request) because we have enough processors to service the running threads?

- 7,983
- 3
- 57
- 80

- 15,639
- 133
- 442
- 830
-
12FWIW, calling `Thread.yield()` is a mild code smell. It's not as bad as calling `sleep()`, but I certainly get suspicious when I see it. Often it's used by threads that poll for changes when they should be waiting for a monitor, listening for events, registering async callbacks, etc., instead. – John Kugelman May 08 '19 at 15:59
-
@JohnKugelman it seems that if waiting is involved, `Thread::onSpinWait` was added in java-9. I still can't tell which one to use though and when. – Eugene May 09 '19 at 09:23
3 Answers
Whenever a thread calls the Thread.yield()
method, it gives a hint to the thread scheduler that it is ready to pause its execution. The thread scheduler is free to ignore this hint.
If any thread executes the yield method, the thread scheduler checks if there is any runnable (waiting to be executed) thread with same or high priority than this thread. If the processor finds any thread with higher or same priority then it will switch to a new thread. If not, the current thread keeps executing.
Since, in your example, you have enough processors to service all the Threads (they are running, not waiting in a runnable state); Thread.yield()
will do nothing, and your threads will continue their execution.
A note about Windows, from Microsoft DOTNet:
This method is equivalent to using platform invoke to call the native Win32 SwitchToThread function.
Yielding is limited to the processor that is executing the calling thread. The operating system will not switch execution to another processor, even if that processor is idle or is running a thread of lower priority. If there are no other threads that are ready to execute on the current processor, the operating system does not yield execution
So there may be caveats in some situations.

- 3,253
- 1
- 22
- 47

- 5,905
- 2
- 31
- 59
-
1In your answer you didn't touch on the number of processors available to run the threads. How is that considered? Specifically my example deals with two processors and two threads. – Dave May 08 '19 at 15:39
-
4Note that your OS will certainly have lots of other processes running and some may want CPU time. – John Kugelman May 08 '19 at 15:56
-
4@Dave, Re, "...touch on the number of processors..." The number of processors is not relevant. `Thread.yield()`, if it does anything at all, tells the scheduler that the caller (a) still has work to do, (b) does _not want_ to give up the processor it's running on, but (c) is _willing_ to give up the processor _if_ some other thread wants it. The only processor that matters is the one that the caller is running on. The only number that matters is the number of other threads that want a processor to run on (specifically, whether that number is zero, or greater than zero.) – Solomon Slow May 08 '19 at 18:31
-
There will never be any ready threads with a higher priority - they would be running already:) – Martin James May 09 '19 at 09:31
Thread.yield()
is obsolete. Unless your program is going to run on a platform that implements cooperative multitasking or on a JVM that still uses green threads, then there is no point in calling it.
The standard library Javadoc for Thread.yield()
effectively says that yield()
does not have to do anything at all.

- 25,130
- 5
- 37
- 57
-
4I doubt it is obsolete - look in the jdk classes internally - lots of usages of it. – Eugene May 09 '19 at 09:25
-
1
I always thought that Thread::yield
should be replaced with Thread::onSpinWait
(since java 9) - that is just a form of a "weaker" yield, until I saw a usage of both in StampedLock
:
else if ((LockSupport.nextSecondarySeed() & OVERFLOW_YIELD_RATE) == 0)
Thread.yield();
else
Thread.onSpinWait();
return 0L;
So I don't think it is obsolete. Internally in the jdk sources it has many usages, even the relatively new ForkJoinPool
has usages of Thread::yield
.
In practice, I have only used Thread::onSpinWait
inside busy spins - because at least from the name of it - it is very clear when to use it; yielding on the other hand is not - so I can't tell for sure when and how to use it.
Just my 0.02$.

- 117,005
- 15
- 201
- 306