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 callSleep(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 WindowsSwitchToThread()
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?
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;
}
};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 enclosingswitch
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 theExpression
becomes the value of theswitch
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 ayield
statement is void (15.1).
Execution of a
yield
statement first evaluates theExpression
. If the evaluation of theExpression
completes abruptly for some reason, then theyield
statement completes abruptly for that reason. If evaluation of theExpression
completes normally, producing a valueV
, then theyield
statement completes abruptly, the reason being a yield with valueV
.
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 Field
s 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
How Does Java Store Strings and How Does Substring Work Internally
Ejb 3.1 @Localbean VS No Annotation
Spring Configure @Responsebody JSON Format
What Is the Best/Simplest Way to Read in an Xml File in Java Application
How to Add a New Sourceset to Gradle
Stopping a Window from Displaying Till It Is Fully Drawn
Error Message "Unreported Exception Java.Io.Ioexception; Must Be Caught or Declared to Be Thrown"
How to Set a Jlabel's Background Color
Why Is Executing Java Code in Comments with Certain Unicode Characters Allowed
Difference Between @Onetomany and @Elementcollection
Time Complexity of Java's Substring()
Java: Object to Byte[] and Byte[] to Object Converter (For Tokyo Cabinet)
Setting Active Profile and Config Location from Command Line in Spring Boot
Output an Image File from a Servlet
How to Sort Arraylist<Long> in Decreasing Order
Java Split Is Eating My Characters
Why Can't We Use '==' to Compare Two Float or Double Numbers
Can Spring Security Use @Preauthorize on Spring Controllers Methods