What Are the Main Uses of Yield(), and How Does It Differ from Join() and Interrupt()

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.

Is Thread.yield same as non blocking IO in Java

TL;DR: No, Thread.yield() can't and shouldn't be used for anything.

The mechanism may seem similar, but yield() is not related to and cannot be used to implement non-blocking IO. It's also cumbersome, behaviour is platform dependent, and therefore should not be used.

While blocking IO works by having a thread "lock itself" on an input stream and wake up when input arrives, non-blocking IO reverses this and there's a central selector (a native mechanism) that gets notified when input data is available. It can observe thousands of channels at the same time, and spend zero resources on those that don't require any attention. When data is available on a channel, the selector then directs that data to a worker thread to process. It's efficient, but also different and more complicated than blocking IO.

Since yield() only tells the CPU that "I have no work to do, feel free to run other threads while I rest", it's still working in the same way as regular IO. You want to avoid threads that don't have anything to do, and yielding is just actively not doing anything, instead of letting the scheduler determine it.

Now you might think you could write something like the following to simulate non-blocking IO

List<InputStream> ins ...
while(true) {
for(InputStream in : ins) {
if(in.available() > 0) {
int input = in.read();
// do something with input
}
}
Thread.yield();
}

You might think that the code acts like a selector. Going through the blocking input streams, checking if they have data to read, if so, reading the data and processing it, and maybe yielding the thread after the loop for good measure.

The above code is flawed mainly because of the call to InputStream.available(). It can be used to tell when a call will not block if it returns a positive number, but it can return 0 and still not block. You might (and very possibly will) end up looping over those streams forever and not read anything because the logic thinks it will block because available() returns 0 just because it cannot be sure that it won't block. This is the major difference between blocking and non-blocking IO. The only sure way to know if a read will block with BIO, is to call read(). And then you might be stuck.

Here's Stephen's good explanation of problems with available() in socket programming.

What is difference between sleep() method and yield() method of multi threading?

sleep() causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).

yield() basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should. Otherwise, the current thread will continue to run.

What does the new keyword yield mean in Java 13?

Q&A

How can I use it?

  1. With arrow labels when a full block is needed:

    int value = switch (greeting) {
    case "hi" -> {
    System.out.println("I am not just yielding!");
    yield 1;
    }
    case "hello" -> {
    System.out.println("Me too.");
    yield 2;
    }
    default -> {
    System.out.println("OK");
    yield -1;
    }
    };
  2. With traditional blocks:

    int value = switch (greeting) {
    case "hi":
    System.out.println("I am not just yielding!");
    yield 1;
    case "hello":
    System.out.println("Me too.");
    yield 2;
    default:
    System.out.println("OK");
    yield -1;
    };

What's the difference to a default return?

A return statement returns control to the invoker of a method (§8.4, §15.12) or constructor (§8.8, §15.9) while a yield statement transfers control by causing an enclosing switch expression to produce a specified value.

What's the difference to a break value?

The break with value statement is dropped in favour of a yield statement.

Specification

There is Specification for JEP 354 attached to the JLS 13 which sums up everything we need to know about the new switch. Note that it wasn't merged into the language specification because it's still a preview feature and, thus, not yet a permanent part of the language.

A yield statement transfers control by causing an enclosing switch expression to produce a specified value.

YieldStatement:
yield Expression;

A yield statement attempts to transfer control to the innermost enclosing switch expression; this expression, which is called the yield target, then immediately completes normally and the value of the Expression becomes the value of the switch expression.

  • It is a compile-time error if a yield statement has no yield target.

  • It is a compile-time error if the yield target contains any method, constructor, initializer, or lambda expression that encloses the yield statement.

  • It is a compile-time error if the Expression of a yield statement is void (15.1).


Execution of a yield statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the yield statement completes abruptly for that reason. If evaluation of the Expression completes normally, producing a value V, then the yield statement completes abruptly, the reason being a yield with value V.

What or who should interrupt a Thread?

What he means is that if you don't know what a thread does and how it works, you should not interrupt it. Since all threads can be interrupted, it is logical to have an interrupt() method in class Thread.

You could ask the same thing for many other methods that can do "harm" when executed at the wrong place. The methods are the tools, and the programmer must use these tools wisely in order to create a program that works correctly.

Threads just stops working Java

What you get is a typical deadlock.

Consider the case of the two Fields A at x=0, y=0 and B at x=1, y=0.

At some point in time the Field A tries to calculate averageColor() - during this time it holds on lock on itself (since averageColor() is synchronized). Part of this calculation is calling getColor(..) on Field B, which is synchronized on Field B.

If at the same time Field B tries to calculate its averageColor(), Field B holds a lock on itself (so Field A cannot call getColor(..) on Field B). Part of this calculation is in turn to call getColor(..) on Field A - which blocks since Field A is holds a lock on itself and tries to call getColor(..) on Field B.

yield() method not working as expected

As with almost all aspects of Multithreading, even your case isn't guaranteed to behave as expected. Thread.yield() is just like a suggestion to the OS telling - if it is possible, then please execute other threads before this one. Depending on the architecture of your system (number of cores, and other aspects like affinity etc etc) the OS might just ignore your request.

Also, after JDK6U23, the JVM might just change your code to :

   public void run() {
for(int i=0;i<=5;i++) {
// 3 is too darn small. and yield() is not necessary
// so let me just iterate 6 times now to improve performance.
System.out.println(i+Thread.currentThread().toString());

}

yield() can totally be ignored (which might be happening in your case. If you are getting the same result over and over again)



Related Topics



Leave a reply



Submit