What are the main uses of yield(), and how does it differ from join() and interrupt()?

Source: http://www.javamex.com/tutorials/threads/yield.shtml

Windows

In the Hotspot implementation, the way that Thread.yield() works has
changed between Java 5 and Java 6.

In Java 5, Thread.yield() calls the Windows API call Sleep(0). This
has the special effect of clearing the current thread’s quantum and
putting it to the end of the queue for its priority level. In other
words, all runnable threads of the same priority (and those of greater
priority) will get a chance to run before the yielded thread is next
given CPU time. When it is eventually re-scheduled, it will come back
with a full full quantum, but doesn’t “carry over” any of the
remaining quantum from the time of yielding. This behaviour is a
little different from a non-zero sleep where the sleeping thread
generally loses 1 quantum value (in effect, 1/3 of a 10 or 15ms tick).

In Java 6, this behaviour was changed. The Hotspot VM now implements
Thread.yield() using the Windows SwitchToThread() API call. This call
makes the current thread give up its current timeslice, but not its
entire quantum. This means that depending on the priorities of other
threads, the yielding thread can be scheduled back in one interrupt
period later
. (See the section on thread scheduling for more
information on timeslices.)

Linux

Under Linux, Hotspot simply calls sched_yield(). The consequences of
this call are a little different, and possibly more severe than under
Windows:

  • a yielded thread will not get another slice of CPU until all other threads have had a slice of CPU;
  • (at least in kernel 2.6.8 onwards), the fact that the thread has yielded is implicitly taken into account by the scheduler’s heuristics
    on its recent CPU allocation— thus, implicitly, a thread that has
    yielded could be given more CPU when scheduled in the future.

(See the section on thread scheduling for more details on priorities
and scheduling algorithms.)

When to use yield()?

I would say practically never. Its behaviour isn’t standardly defined
and there are generally better ways to perform the tasks that you
might want to perform with yield():

  • if you’re trying to use only a portion of the CPU, you can do this in a more controllable way by estimating how much CPU the thread
    has used in its last chunk of processing, then sleeping for some
    amount of time to compensate: see the sleep() method;
  • if you’re waiting for a process or resource to complete or become available, there are more efficient ways to accomplish this,
    such as by using join() to wait for another thread to complete, using
    the wait/notify mechanism to allow one thread to signal to another
    that a task is complete, or ideally by using one of the Java 5
    concurrency constructs such as a Semaphore or blocking queue.

Leave a Comment