JVM not exiting until daemon thread not completed - java

I just stumbled upon a weird behavior of daemon threads which I can't explain. I've reduced my code to a minimal, complete and verifiable sample:
public static void main(String[] args) throws InterruptedException {
Thread runner = new Thread(() -> {
final int SIZE = 350_000;
for (int i = 0; i < SIZE; i++) {
for (int j = i + 1; j < SIZE; j++) {
if (i*j == SIZE * SIZE - 1) {
return;
}
}
}
});
runner.setDaemon(true);
runner.start();
// Thread.sleep(1000);
System.out.println("Exiting.");
}
The code executed by the runner thread takes about 12 secs to terminate on my box, and we're not interested in what it does, since I just needed to spend some time computing.
If this snippet is run as it is, it works as expected: it terminates just after its start.
If I uncomment the Thread.sleep(1000) line and run the program, it works for about 12 seconds, then prints out "Exiting" and terminates.
As far as I understood how daemon threads work, I expected this code to run for 1 second and then to terminate execution, since the only user thread running is the one launched with the main() method (the runner is a background daemon thread) and as soon as the 1000 msec are passed, it reaches the end of its execution and the JVM should stop. Also, it looks quite strange that "Exiting" is printed only after 12 seconds, and not when the program starts.
Am I wrong? How can I achieve the desired behavior (pause for a second and then stop, independently from what the runner thread is doing)?
I'm using a 64bit Oracle JDK 1.8.0_112 on a linux box and it has the same behavior either if launched from an IDE or from the command line.
Thanks,
Andrea

This is maybe a consequence of counted loop optimization which removed safepoint polls from your nested loops. Try to add -XX:+UseCountedLoopSafepoint flag to your JVM startup options.

Thread#sleep(long) pauses the main thread before it returns from its main method (i.e. before the JVM is considering the program done as long as no non-deamon threads are alive). The scheduler is then free to run any other runnable thread which would be the deamon thread. As it stands, there is no apparent reason for the JVM to forcibly preempt the deamon thread before it finishes execution to continue in the main thread (is it's done sleeping yet), so the JVM is free to continue its schedule. However, it may at any time elect to pause the running thread and schedule another runnable thread for execution, so reproducibility is not guaranteed for your example.
You can force a preemption by inserting calls to Thread#yield() or #sleep(1) in the loops. I bet you'll start seeing the snippet exiting faster and before it finishes the loops.
There's more to learn about Thread states and scheduling, a nice overview can be found here.
Update for comment:
I cannot modify the code in the background thread (is a requirement), so I was looking for a way to stop it if it takes too long (a description of what I'm doing is stackoverflow.com/questions/41226054/… ).
It's legally only possible to stop a running thread from within, so you usually have it test an abort condition every iteration, and if the condition is met, the run method return;s. An abort condition could be as simple as a boolean flag that is set from the outside (! volatile caveat !). So the dead-simplest solution would be to have the main thread set such a flag after the sleep.
Another possibility might be using an ExecutorService that supports timeouts, see this Q&A for an example involving ScheduledExecutorService.
Still I don't understand how the scheduler can decide to wait for 12 seconds before running the System.out instruction.
It does not wait 12 seconds, it let's the deamon thread run to completion because being a deamon only matters to the JVM when deciding if it's safe to halt the JVM. For the scheduler, only the state of the thread matters and as far as it's concernced, after the 1s sleep of the main thread, it has a running (deamon) and a runnable thread (main), and no indication that the running thread should be paused in favor for the runnable thread. Switching threads is also expensive computationally, so the scheduler might be reluctant lacking any indication. An indication to switch might be sleeps and yields, but also GC runs and a whole lot of other things.

Related

Is blocking main method in Java always bad?

We have an application that's continuously running. Nothing much goes on in the main method except initializing a few background threads. The background threads process socket events as they occur. Apart from the time the socket events are being processed, app remains in the idle state.
Main
Start Thread 1 -> while(socket connection 1 is good) -> process events
Start Thread 2 -> while(socket connection 2 is good) -> process events
Start Thread 3 -> while(socket connection 3 is good) -> process events
Start Thread 4 -> while(socket connection 4 is good) -> process events
while (true); // block main thread from exiting. Otherwise, periodic GC calls kills the app.
As the primary function of my app is to process events and there is not foreground tasks as such. Does blocking main thread is bad in my case? What are some other alternates?
the main thread is just the first thread, and as such is not different from any other thread. If you block it, it means waste of memory occupied by this thread (about 1MB) and nothing more. So I would just return from the main method, if there is no job for this thread.
I noticed a comment in your code: block main thread from exiting. Otherwise, periodic GC calls kills the app. The comment is wrong. GC calls cannot kill the application. I suspect other threads are started in daemon mode, and so the enclosing process does not wait for them to finish.
If you describe in more details when the whole process must end, we could make more sensible advises.
Since your main thread does busy waiting it will require thread scheduler to it (main thread) into list of scheduled threads. And if your machine where you are running your app has less then 4 CPUs then your event processing threads will suffer.
There are a lot of other ways to block your main thread without busy waiting. Thread.join() as mentioned above is one of them. You can also use Future.get(), or ExecutorService.awaitTermination() if you use high level concurrency objects.
Yes, it's a bad design. Use a ExecutorService and add the threads to it.
Blocking in the main method (or from any other thread) should be avoided. The problem you are running into – how to create some threads and keep the JVM running until those threads finish – can be solved in better ways.
If you create a new Thread and call setDaemon(false), then you won't need to do anything with sleeping or waiting. By setting the thread to be non-daemon, the JVM will stay running until that thread completes. From the Javadoc:
The Java Virtual Machine exits when the only threads running are all daemon threads.
Here's an example thread class that tries to sleep for 2 seconds, then prints out a message:
class ExampleThread extends Thread {
#Override
public void run() {
try {
sleep(2000);
System.out.println("done sleeping");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If you call it like this – by setting daemon to false – you will first see
output thread started, followed by 2 seconds of nothing, then output done sleeping.
public static void main(String[] args) {
ExampleThread t = new ExampleThread();
t.setDaemon(false);
t.start();
System.out.println("thread started");
}
If you replace t.setDaemon(false) with this t.setDaemon(true) – so that the new thread is in fact a daemon thread – then you will see output thread started followed by immediate JVM termination.

Interrupt Runnable that takes hours

I have a ThreadPoolExecutor:
ThreadPoolExecutor service = new ThreadPoolExecutor(N_THREADS, N_THREADS, 0L, TimeUnit.MILLISECONDS, blockingQueue, rejectedExecutionHandler);
The service executes threads implementing the Runnable interface. Each thread processes a file on disk. I found that after several hours, two threads (or cores depending on what htop shows in Linux) were running and had been running for 13 hours. What's even worse is that the remaining cores showed no activity as if they were waiting for the two threads to complete.
Questions:
1 - I have read a lot on how this problem may be resolved but nothing conclusive. As far as I can work out, you CANNOT stop a Runnable using the ThreadPoolExecutor because it is an independent thread that just runs. Using the Future framework:
Future<?> f = f.get(submittedtask,XX)
allows you to set a timeout and fetch the future result, but get blocks all the threads effectively making the implementation serial. Is it possible to interrupt a Runnable after a given time using the threadpoolexecutor, get the thread back to the pool so it can pickup a new task and carry on.
2 - My big concern is why, using htop, I see two threads/cores running and no other core/thread are running despite many tasks are still waiting to execute (i.e. there are many files left to process). Any insight?
You could create a second scheduled thread pool to which you would submit cancellation tasks for each of the returned Futures. Each of these tasks after a given timeout would check if it's associated Future is done and if not, cancel it. Cancellation would trigger thread interruption, so you might need to support it in your tasks by checking the interrupted flag: Thread.interrupted().
The size of this second thread pool could be minimal, i.e. 1 as this job takes minimum of CPU time.
Code example:
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
...
while(...){
final Future<?> f = pool.submit(...);
service.schedule(new Runnable() {
#Override
public void run() {
if(!f.isDone()){
f.cancel(true);
}
}
}, 1, TimeUnit.MINUTES);
}
service.awaitTermination(1, TimeUnit.MINUTES);
service.shutdown();
You can tell a thread that you wish to interrupt:
An interrupt is an indication to a thread that it should stop what it is doing and do something else.
You can interrupt your thread with Future.cancel(true). It's in your responsibility to implement the Runnable in a manner that it obeys that wish by checking its Thread.interrupted() state.
In order to see details about process thread run:
ps -eLf | grep <PROCESS_PID>
Since htop shows you the running processes list, where each process has at least one thread.

How can I brutally and mercilessly abort a task in Java?

I programmed a sudoku solver in Java for a homework, and I am currently trying to figure out the problematic inputs it can face to make it better. I have generated a few thousand sudoku grids with David Bau's sudoku generator, and now I am running my program against them.
The problem is that while most of them complete in very reasonable times, some of them prove to be problematic and make my algorithm search like crazy until I run out of heap space. So I thought I should offshore the solving job to a secondary thread and run it with a timeout. Right now, I'm using a thread 'pool' of one thread (in the form of an ExecutorService) and I'm submitting Callables to it. I then try to get the value with a timeout:
Callable<Long> solveAndReturnTime = new Callable<Long>() { /* snip */ };
Future<Long> time = executor.submit(solveAndReturnTime);
try
{
long result = time.get(10, TimeUnit.SECONDS);
System.out.printf("%d millis\n", result);
}
catch (TimeoutException e)
{
System.err.println("timed out");
time.cancel(true);
}
My problem is that apparently, one does not simply cancel a Future in Java. Future<T>.cancel(boolean) apparently doesn't interrupt the task right away. Because of that, the pool is stuck with carrying an undying task, and the subsequent attempts timeout because they never get a chance to run.
Adding more threads to the pool is not an option because I run on limited cores and if too many tasks obstinately run, the legitimate ones will be unfairly slowed down. I also don't want the overhead of frequently checking if the task was aborted from my main algorithm.
How can I abruptly, mercilessly and brutally terminate a task? I'm open to anything that will let me recover on the main thread.
EDIT My algorithm is completely sequential, uses no global object, and contains no lock. As far as I can tell, nothing will go wrong if the task is cancelled at a random moment; and even if it does, it's not production code. I'm ready to walk the dangerous and treacherous walk for this one.
Just as in any other language methods to mercifully terminate a thread are Deprecated or not recommended. Because such methods may cause deadlocks (a thread being terminated will not release the locks it's holding).
The correct solution to the problem is having an additional check for Thread.currentThread ().isInterrupted () on every iteration of the main cycle in you Callable. So when the thread is being interrupted it would see it and gracefully shut down.
And since it's you code running in another thread it shouldn't be difficult for you to modify it.
In addition to Andrei's answer, which is correct, you should be aware that doing this work in a thread will not protect your application from running out of memory via an OOM. If your worker thread consumes the entire heap, the main thread can very well die too.
I believe my case was 'special' enough to use Thread.stop, so here is my solution to the people who believe their case is special enough too. (I would take extreme care using that somewhere it could actually matter, though.)
As mostly everyone points out, there's no clean way to stop a task without having that task check if it should stop itself. I created a class that implements Runnable to carry out in such a way that it won't be dramatic if it's killed. The result field (milliseconds) is an AtomicLong because writes on regular long variables are not guaranteed to be atomic.
class SolveTimer implements Runnable
{
private String buildData;
private AtomicLong milliseconds = new AtomicLong(-1);
public SolveTimer(String buildData)
{
assert buildData != null;
this.buildData = buildData;
}
public void run()
{
long time = System.currentTimeMillis();
// create the grid, solve the grid
milliseconds.set(System.currentTimeMillis() - time);
}
public long getDuration() throws ContradictionException
{
return milliseconds.get();
}
}
My code creates a thread on each iteration and runs a SolveTimer. It then attempts to join within 10 seconds. After join returns, the main thread calls getDuration on the run timer; if it returns -1, then the task is taking too long and the thread is killed.
SolveTimer timer = new SolveTimer(buildData);
Thread worker = new Thread(timer);
worker.start();
worker.join(10000);
long result = timer.getDuration();
if (result == -1)
{
System.err.println("Unable to solve");
worker.stop();
}
It should be noted that this makes worker threads harder to debug: when the thread is suspended by the debugger, it can still be killed by Thread.stop(). On my machine, this writes a short error message about ThreadDeath in the console and crashes the Java process.
There is a possible race condition where the worker thread completes exactly (or right after) getDuration is called, and because of that result will be -1 even if the task actually succeeded. However, that's something I can live with: 10 seconds is already far too long, so at that point I don't really care anymore if it's nearly good enough.

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

I am a little bit confused about the use of Thread.yield() method in Java, specifically in the example code below. I've also read that yield() is 'used to prevent execution of a thread'.
My questions are:
I believe the code below result in the same output both when using yield() and when not using it. Is this correct?
What are, in fact, the main uses of yield()?
In what ways is yield() different from the join() and interrupt() methods?
The code example:
public class MyRunnable implements Runnable {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
for(int i=0; i<5; i++) {
System.out.println("Inside main");
}
}
public void run() {
for(int i=0; i<5; i++) {
System.out.println("Inside run");
Thread.yield();
}
}
}
I obtain the same output using the code above both with and without using yield():
Inside main
Inside main
Inside main
Inside main
Inside main
Inside run
Inside run
Inside run
Inside run
Inside run
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.
I see the question has been reactivated with a bounty, now asking what the practical uses for yield are. I'll give an example from my experience.
As we know, yield forces the calling thread to give up the processor that it's running on so that another thread can be scheduled to run. This is useful when the current thread has finished its work for now but wants to quickly return to the front of the queue and check whether some condition has changed. How is this different from a condition variable? yield enables the thread to return much quicker to a running state. When waiting on a condition variable the thread is suspended and needs to wait for a different thread to signal that it should continue. yield basically says "allow a different thread to run, but allow me to get back to work very soon as I expect something to change in my state very very quickly". This hints towards busy spinning, where a condition can change rapidly but suspending the thread would incur a large performance hit.
But enough babbling, here's a concrete example: the wavefront parallel pattern. A basic instance of this problem is computing the individual "islands" of 1s in a bidimensional array filled with 0s and 1s. An "island" is a group of cells that are adjacent to eachother either vertically or horizontally:
1 0 0 0
1 1 0 0
0 0 0 1
0 0 1 1
0 0 1 1
Here we have two islands of 1s: top-left and bottom-right.
A simple solution is to make a first pass over the entire array and replace the 1 values with an incrementing counter such that by the end each 1 was replaced with its sequence number in row major order:
1 0 0 0
2 3 0 0
0 0 0 4
0 0 5 6
0 0 7 8
In the next step, each value is replaced by the minimum between itself and its neighbours' values:
1 0 0 0
1 1 0 0
0 0 0 4
0 0 4 4
0 0 4 4
We can now easily determine that we have two islands.
The part we want to run in parallel is the the step where we compute the minimums. Without going into too much detail, each thread gets rows in an interleaved manner and relies on the values computed by the thread processing the row above. Thus, each thread needs to slightly lag behind the thread processing the previous line, but must also keep up within reasonable time. More details and an implementation are presented by myself in this document. Note the usage of sleep(0) which is more or less the C equivalent of yield.
In this case yield was used in order to force each thread in turn to pause, but since the thread processing the adjacent row would advance very quickly in the meantime, a condition variable would prove a disastrous choice.
As you can see, yield is quite a fine-grain optimization. Using it in the wrong place e.g. waiting on a condition that changes seldomly, will cause excessive use of the CPU.
Sorry for the long babble, hope I made myself clear.
About the differences between yield(), interrupt() and join() - in general, not just in Java:
yielding: Literally, to 'yield' means to let go, to give up, to surrender. A yielding thread tells the operating system (or the virtual machine, or what not) it's willing to let other threads be scheduled in its stead. This indicates it's not doing something too critical. It's only a hint, though, and not guaranteed to have any effect.
joining: When multiple threads 'join' on some handle, or token, or entity, all of them wait until all other relevant threads have completed execution (entirely or upto their own corresponding join). That means a bunch of threads have all completed their tasks. Then each one of these threads can be scheduled to continue other work, being able to assume all those tasks are indeed complete. (Not to be confused with SQL Joins!)
interruption: Used by one thread to 'poke' another thread which is sleeping, or waiting, or joining - so that it is scheduled to continue running again, perhaps with an indication it has been interrupted. (Not to be confused with hardware interrupts!)
For Java specifically, see
Joining:
How to use Thread.join? (here on StackOverflow)
When to join threads?
Yielding:
Interrupting:
Is Thread.interrupt() evil? (here on StackOverflow)
First, the actual description is
Causes the currently executing thread object to temporarily pause and
allow other threads to execute.
Now, it is very likely that your main thread will execute the loop five times before the run method of the new thread is being executed, so all the calls to yield will happen only after the loop in the main thread is executed.
join will stop the current thread until the thread being called with join() is done executing.
interrupt will interrupt the thread it is being called on, causing InterruptedException.
yield allows a context switch to other threads, so this thread will not consume the entire CPU usage of the process.
The current answer(s) are out-of-date and require revision given recent changes.
There is no practical difference of Thread.yield() between Java versions since 6 to 9.
TL;DR;
Conclusions based on OpenJDK source code (http://hg.openjdk.java.net/).
If not to take into account HotSpot support of USDT probes (system tracing information is described in dtrace guide) and JVM property ConvertYieldToSleep then source code of yield() is almost the same. See explanation below.
Java 9:
Thread.yield() calls OS-specific method os::naked_yield():
On Linux:
void os::naked_yield() {
sched_yield();
}
On Windows:
void os::naked_yield() {
SwitchToThread();
}
Java 8 and earlier:
Thread.yield() calls OS-specific method os::yield():
On Linux:
void os::yield() {
sched_yield();
}
On Windows:
void os::yield() { os::NakedYield(); }
As you can see, Thread.yeald() on Linux is identical for all Java versions.
Let's see Windows's os::NakedYield() from JDK 8:
os::YieldResult os::NakedYield() {
// Use either SwitchToThread() or Sleep(0)
// Consider passing back the return value from SwitchToThread().
if (os::Kernel32Dll::SwitchToThreadAvailable()) {
return SwitchToThread() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
} else {
Sleep(0);
}
return os::YIELD_UNKNOWN ;
}
The difference between Java 9 and Java 8 in the additional check of the existence of the Win32 API's SwitchToThread() method. The same code is present for Java 6.
Source code of os::NakedYield() in JDK 7 is slightly different but it has the same behavior:
os::YieldResult os::NakedYield() {
// Use either SwitchToThread() or Sleep(0)
// Consider passing back the return value from SwitchToThread().
// We use GetProcAddress() as ancient Win9X versions of windows doen't support SwitchToThread.
// In that case we revert to Sleep(0).
static volatile STTSignature stt = (STTSignature) 1 ;
if (stt == ((STTSignature) 1)) {
stt = (STTSignature) ::GetProcAddress (LoadLibrary ("Kernel32.dll"), "SwitchToThread") ;
// It's OK if threads race during initialization as the operation above is idempotent.
}
if (stt != NULL) {
return (*stt)() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
} else {
Sleep (0) ;
}
return os::YIELD_UNKNOWN ;
}
The additional check has been dropped due to SwitchToThread() method are available since Windows XP and Windows Server 2003 (see msdn notes).
What are, in fact, the main uses of yield()?
Yield suggests to the CPU that you may stop the current thread and start executing threads with higher priority. In other words, assigning a low priority value to the current thread to leave room for more critical threads.
I believe the code below result in the same output both when using yield() and when not using it. Is this correct?
NO, the two will produce different results. Without a yield(), once the thread gets control it will execute the 'Inside run' loop in one go. However, with a yield(), once the thread gets control it will print the 'Inside run' once and then will hand over control to other thread if any. If no thread in pending, this thread will be resumed again. So every time "Inside run' is executed it will look for other threads to execute and if no thread is available, the current thread will keep on executing.
In what ways is yield() different from the join() and interrupt() methods?
yield() is for giving room to other important threads, join() is for waiting for another thread to complete its execution, and interrupt() is for interrupting a currently executing thread to do something else.
Thread.yield() causes thread to go from "Running" state to "Runnable" state.
Note: It doesn't cause thread to go "Waiting" state.
Thread.yield(); frees the bottom thread.
Thread is using OS threads, so Thread.yield(); might free the hardware thread.
Bad implementation for sleep(millis)
public class MySleep {
public static void sleep(long millis) throws InterruptedException {
long start = System.currentTimeMillis();
do {
Thread.yield();
if (Thread.interrupted()) {
throw new InterruptedException();
}
} while (System.currentTimeMillis() - start < millis);
}
}
and join()
public class MyJoin {
public static void join(Thread t) throws InterruptedException {
while (t.getState() != Thread.State.TERMINATED) {
Thread.yield();
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
}
public static void main(String[] args) {
Thread thread = new Thread(()-> {
try {
Thread.sleep(2000);
} catch (Exception e) {
}
});
thread.start();
System.out.println("before");
try {
join(thread);
} catch (Exception e) {
}
System.out.println("after");
}
}
This should work even if there is only one hardware thread, unless Thread.yield(); is removed.
Thread.yield()
When we invoke Thread.yield() method, the thread scheduler keep the currently running thread to Runnable state and picks another thread of equal priority or higher priority. If there is no equal and higher priority thread then it reschedule the calling yield() thread. Remember yield method does not make the thread to go to Wait or Blocked state. It can only make a thread from Running State to Runnable State.
join()
When join is invoked by a thread instance, this thread will tell currently executing thread to wait till the Joining thread completes. Join is used in the situations when a task which should be completed before the current task is going to finish.
yield() main use is for putting a multi-threading application on hold.
all these methods differences are yield() puts thread on hold while executing another thread and returning back after the completion of that thread, join() will bring the beginning of threads together executing until the end and of another thread to run after that thread has ended, interrupt() will stop the execution of a thread for a while.

what's the difference between yield() and sleep()?

I know one difference:
If we say thread.sleep(1000), that thread will sleep for 1000 milliseconds for sure, whereas with yield() there is no such guarantee. This is useful for thread scheduling, since the thread which calls yield() may very well selected immediately again for running.
What else?
Thread.sleep()
The current thread changes state from Running to Waiting/Blocked as shown in the diagram below.
Any other thread with reference to the thread currently sleeping (say t) can interrupt it calling t.interrupt()
the call to sleep has to be encapsulated to catch the checked exception of InterruptedException
After the time period for which the thread was set to sleep it goes to the Runnable state and might not run immediately! It has to wait for the Thread Scheduler to schedule it for its time slice.
Thread.yield()
Calling it may cause the Thread Scheduler to move the current thread from Running to Runnable state and execute another same priority thread which was in Runnable state. This transition of state takes place only if there is some other thread of same priority in Runnable state. Hence the no guarantee that the thread will stop execution as the criteria of another same priority thread might not be met.
.yield() is much based on the Thread Priorities concept. (All thread are assigned priorities and when a thread of higher priority is in Runnable state it ususally preempts / stops execution of lower priority threads depending on implementation of ThreadScheduler.)
Note:
both Thread.sleep() and Thread.yield() are static functions and affect the current thread executing it.
both the functions will not let go the synchronized locks they hold.
yield merely says: now is a good time to let another thread run and is a hint to the scheduler. sleep really does that: sleep at least the given time.
yield() pauses momentarily the current thread, allowing the Thread Scheduler to execute other threads with the same priority. If there are no other threads waiting or their priority is lower, the yielded thread returns to its execution at once.
sleep() forces the current thread to halt its execution for a defined slot of time. Other waiting threads will start executing by taking advantage of this pause, that is, following the Thread Scheduler policy - whose implementation is vendor dependent.
It's not "for sure" -- it could even take an hour for your thread to get another chance to run, depending on the operating system's thread scheduling algorithm, and the presence of higher-priority threads.
The only thing yield() does is say, "Okay, I'm kind of done, so feel free to end my time slice and continue executing something else." sleep, on the other hand, says "Wake me up in X milliseconds". sleep is used for waiting, the other one for giving others a chance to run. They're not alternatives.

Categories