How the main thread sleep/interrupt works in following code - java

How the second loop actually interrupts the sleeping main thread, and first does not??
My understanding is after Thread.sleep(3000), the code Thread.currentThread().interrupt() will be executed after 3 seconds.
Can anyone explain how it actually works
for (int i = 0; i < 2; i++) {
try {
System.out.println("loop : " + i);
Thread.sleep(3000);
System.out.println("Woke up");
Thread.currentThread().interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
loop : 0
Woke up
loop : 1
java.lang.InterruptedException: sleep interrupted
exception loop:1
at java.base/java.lang.Thread.sleep(Native Method)
at multithreadings.Mainclass.main(Mainclass.java:13)

Interruption is a polite request to stop: a Thread is under no obligation to stop.
It's like the Robin Williams joke about what police in the UK say when you commit a crime:
Stop! Or I'll say stop again!
Also, interrupting a thread doesn't cause an InterruptedException to be thrown: it merely sets a flag on the thread. If something (like Thread.sleep) checks this flag, and finds that it is set, it may then throw an InterruptedException; but the flag and exception are two orthogonal ways of indicating interruption.
As such:
On the first execution, you sleep for 3 seconds, then set the interrupted flag, and the loop body finishes normally.
On the second execution, you ask to sleep for 3 seconds, but Thread.sleep detects the interrupted flag, and throws the exception.

There is a single thread involved in the code you posted. This thread executes a loop. At the first iteration, the thread interrupts itself. Interrupting doesn't mean "stop executing immediately". It means: "please, I would like you to stop running when you can".
A thread that wants to respect interruption requests can do it in two ways:
It regularly checks if it has been interrupted, and if it's the case, then it stops executing (by breaking out of a loop or returning, for example)
It calls a blocking method such as sleep(), which will throw an InterruptedException if the thread has been interrupted or is being interrupted.
What happens is the second case. A request for interruption is done in the first iteration, after the call to sleep(). The thread continues running, and at the second iteration, it calls sleep(), which throws en InterruptedException because the thread has been interrupted before.

In Java, one thread cannot stop the other thread. A thread can only request the other thread to stop. The request is made in the form of an interruption. Calling the interrupt() method on an instance of a Thread sets the interrupt status state as true on the instance.
All blocking methods respond to interruption by throwing InterruptedException once the interrupt status is set to true. , if you want to check more in detail, please read the below article. See how Thread Interruption works in Java.

Read the documentation, i.e. the javadoc of interrupt():
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, ...
If this thread is blocked ...
If this thread is blocked ...
If this thread is blocked ...
If none of the previous conditions hold then this thread's interrupt status will be set.
and sleep(long millis):
Throws InterruptedException if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
Since the thread has already interrupted itself on the second iteration of the loop, thereby setting it's own interrupted status, the sleep(...) method is immediately interrupted.

Related

What is the difference between wait/notify and wait/interrupt?

synchronized (Foo.class) {
while (someCondition) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
It seems that this thread both wakes when some other thread call interrupt() or notify() on this thread. Are there any differences between the two?
--EDIT--
I know one is for notifying an object, the other interrupts a thread. But both of these lead to the same consequence, that is, this thread is waken up, so what I want to ask is how these 2 situations' consequences are different from each other.
When a thread calls notify on some monitor, it wakes up a single thread that's waiting on that monitor, but which thread gets woken is decided by the scheduler. (Alternatively a thread can call notifyAll, which wakes up all the threads waiting for that monitor, then they all contend for the monitor, then the losers go back to waiting.) That's why the target of the call is different, the notification is made to the monitor, which tells the scheduler to pick a thread to wake up.
Unlike notify, interruption targets a specific thread. And interruption does not require that the interrupted thread be waiting on a monitor. For a thread to call wait on a monitor it has to have acquired that monitor first, then wait releases that monitor until the thread is done waiting or is interrupted.
Oracle's recommendation is to use interruption only for cancellation. Also the classes in java.util.concurrent are designed to use interrupt for cancellation.
In your example interruption won't be very effective, because control doesn't leave the while loop, the thread still has to check the condition it's waiting on, and there's no check in the while loop condition for whether the interrupt flag is set. It's likely the thread that's interrupted will go right back to waiting.
In order to make this code quit once it's interrupted, rather then return to waiting, add a check for the interrupted flag status to the loop condition, and have the catch block set the interrupt flag (which gets reset when the exception is thrown):
synchronized (Foo.class) {
while (someCondition && !Thread.currentThread().isInterrupted()) {
try {
Foo.class.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Basically, you are not looking for a text book difference but difference in their uses cases.
As folks have already pointed out, waking up the thread is not the only consequence but calling t1.interrupt() from Thread t2 for t1 will cause an InterruptedException in thread t1 and that is a big difference between Object.notify() and Thread.interrupt().
You should understand that its method Object.wait() which throws checked InterruptedException and forces you to handle it. Object.wait.
InterruptedException - if any thread interrupted the current thread
before or while the current thread was waiting for a notification. The
interrupted status of the current thread is cleared when this
exception is thrown.
Then you should consult this question to get an idea about handling this exception.
Difference between the two lies in the fact that one is for inter thread communication for usual logical programing stuff ( wait & notify ) and other one ( interrupt) is for preemptive thread cancellation / termination even in cases of blocking operations. You have to note that Java doesn't provide any mechanism to preemptively cancel a thread so you have to use interrupt mechanism for that purpose ( Obviously, if that is needed in your case. You might very well ignore this Exception if not applicable in your case).
Java doesn't restrict your actions after InterruptedException and you can do anything you want but using it for things other than implementing Thread Cancellation Policy is not advised. Thread Cancellation Policy is often ignored and less discussed area when programmers write multi threaded programs and that is why you might be finding it difficult to understand the use case.
What does an API method like BlockingQueue.put(..) is trying to tell you by throwing InterruptedException is that even its blocking operation can be preemptively terminated. Its not necessary that all blocking API methods will provide you that facility.
Cancellation/Termination of a thread using Thread.interrupt() is not a forceful but cooperative mechanism and is just a request not an order.
Your use of e.printStackTrace(); is strongly discouraged since this is usually not an error, if intention is to log it as an error.
Hope it helps !!
Wait method is used to suspend a current thread on an object.
Wait method is not from thread class but from java.lang.Object
Notify method is used to wake the thread waiting on the object.
Notify method is not from thread class but from java.lang.Object.
Interrupt method is used to to indicate the current thread that is
should stop current job execution and can start other job.
Interrupt method is from thread class.
Let see the real life example:
Consider Telephone as Object , Person as Thread.
Suppose for instance A person is using Telephone and B person also wants to use the telephone but as A person i.e (Thread 1) is busy using it unless the work is done acquires a lock on telephone Object now B i.e(Thread 2) tries to use Telephone but as A has acquired lock on it B it goes into wait state until lock is released.
If Telephone object calls wait method it will restrict current thread
which want to use Telephone and it will go into wait state.
If Telephone object calls notify it will signal the thread waiting on
it to acquire lock and proceed with the intended work.
If Person A(Thread 1) is using Telephone object and is in some task
but interrupt method is called then A will be signaled to stop with
current task and may need to do some other task assigned.

Understanding the usage of Thread.interrupt()

I am reading Interrupts from Oracle Docs. I am unable to figure out the following
part. It states that
What if a thread goes a long time without invoking a method that
throws InterruptedException? Then it must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received. For example:
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
I am scratching my head to understand, what does it mean by What if a thread goes a long
time without invoking a method that throws InterruptedException? Secondly, what is the usage
of Thread.interrupted(), it is a way, that thread can send a interrupt to itself? Whats the
practical usage of this scenario? Thanks.
This is a technique to keep the thread available for interruption.
Thread.interrupted() : checks whether present thread (itself) was interrupted by some other thread and clears the interrupted status flag. So it asks itself whether I was interrupted by someone to exit from what I was doing while I was performing a BIG BIG task and not listening to someone.
Imagine what would have happened if that thing was not done.
Suppose one iteration of heavyCrunch() takes 1 min worth of time. So n iterations will take n minutes.
Now suppose after starting the program you decide that you want to exit the program and terminate the program gracefully. So you interrupt the thread that is doing the heavy crunch.
BUT the thread is unknown of the fact that you have interrupted it as it is not checking for the interrupt status. So the program will not end until N Minutes have not completed and you will have to wait for long time.
So to gracefully terminate the thread, it should always keep checking the interrupt status to respond if someone else has requested interruption.
If you interrupt the thread running this code
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
}
it will only set interrupted status in the thread but it will not stop it
Thread.interrupted tests if interrupted status is set (and clears it) so by adding
if (Thread.interrupted()) {
return;
}
to the loop you make the code interruptible
Besides the fact that the phrase
What if a thread goes a long time without invoking a method that throws InterruptedException?
is deeply unclear, i suppose they mean the following:
Usually, if you have a thread that does some work in a while(true) loop, that is, a thread that does not terminate for a long time, you will probably place ANY function that throws InterruptedException in that thread (i.e. Thread.sleep(), a socket read, or anything!). This way, when your thread will be noticed an Interruption, one of those functions will catch it and you will be able to QUIT what you are doing in the thread (the thread does not just magically terminate itself).
Here comes what the phrase wanted to say:
WHAT IF YOU DO NOT WANT/HAVE to use these functions? Then you should use Thread.interrupted() to check whether you should QUIT doing what the thread is doing in the same way you would do if you catched an InterruptedException.
I hope this was clearer than the doc...
You can use interrupted() stop nicely any long running thread by intrrup thread somewhere and check the condition by Thread.interrupted() and based on this come out of run method.
Let say you one thread is blocked on some monitor and somewhere else that thread got interrupted which inturn will throw InterruptedExceptionand can come out of block state with interrupted status true.
I think interrupt is the best way to achieve stop long running task because an interrupt will unblock some blocking IO and synchronization requests. A bespoke solution cannot do this.
May help you.
interrupt() sets from outside a flag in the object that can then be queried periodically by Interrupted() in the run() method.
I am scratching my head to understand, what does it mean by What if a thread goes a long time without invoking a method that throws InterruptedException?
A: If other thread call the interupt() method of this thread, and if this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. Otherwise, just set the interrupt status.
Secondly, what is the usage of Thread.interrupted(), it is a way, that thread can send an interrupt to itself? What's the practical usage of this scenario?
A: Thread.interrupted() is use to detect current thread's interrupt status, return true if it's set and then clear the status. You check this in order to respond to other thread's interrupt call, such as throw an InterruptedException and exit the thread or just exit.

Java InterruptedException suspends thread?

This should be a simple take for any Java Master. Me being a newbie just wanted to confirm one thing.
I have a class implementing Runnable and like many such classes its run() method has an infinite loop. I want to do some task and then sleep for a min and come back again.
What happens if an Interrupted Exception is encountered while a thread is sleeping?
What I think would happen is the thread being suspended and now the infinite loop is of no help to keep the thread runnning. I'd like to confirm if my understanding is correct or not.
If this is what happens, What would be a possible solution to start up the thread up again.?
Wrong.
An InterruptedException would just terminate the sleep() call and throw an exception.
As long as you handle the exception appropriately, your thread will continue running.
Your understanding is mostly correct - When your thread is sleeping , if it gets interrupted , this will cause an InterruptedException to be thrown - your code in run() will have to catch it and do what it wants to do. The thread itself will not be suspended - because active execution continues on this thread.
You may want to continue the execution of the thread after you handle the InterruptedException in your catch block.
The thread will not be suspended.
If you catch the InterruptedException, execution will continue in your exception handler.
If you do not catch the InterruptedException, the thread will terminate.
InterruptedExceptions don't just happen. Some exceptions, like IOExceptions, happen unpredictably due to inherent flakiness of the medium, but that is not the case for interruptions.
Interruption is a deliberate signal to a thread, usually sent by the application while it is shutting down, that it should finish up what it's doing and stop running. If the thread getting interrupted happens to be waiting or sleeping at the time, then the thread gets woken up and an InterruptedException gets thrown from the wait or sleep method.
Useful libraries like java.util.concurrent and guava use interrupts for thread cancellation. If you try to use them for something else then you can't use those libraries.

java ensure completion of a thread without interruption

I have many threads running, but I want to execute a particular thread (a TimerTask's run() method) to run to its completion and I don't want any interruption by any other threads.
I think synchronized(this) { } wont ensure its completion.
Please suggest me a correct way to do this.
You can catch InterruptedException and set interrupt status once your work is completed.
Noncancelable tasks
Some tasks simply refuse to be interrupted, making them noncancelable. However, even noncancelable tasks should attempt to preserve the interrupted status in case code higher up on the call stack wants to act on the interruption after the noncancelable task completes. Listing 6 shows a method that waits on a blocking queue until an item is available, regardless of whether it is interrupted. To be a good citizen, it restores the interrupted status in a finally block after it is finished, so as not to deprive callers of the interruption request. (It can't restore the interrupted status earlier, as it would cause an infinite loop -- BlockingQueue.take() could poll the interrupted status immediately on entry and throws InterruptedException if it finds the interrupted status set.)
public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
In general you can't prevent a Thread to be "interrupted" but this does not mean that the computation will be cancelled; just that any sleep/wait operations will throw an Exception.
See javadoc.
If you don't want to exit then, you can catch the InterruptedException and swallow it.
'Actually one critical thread which I want to run to its completion
does not do so, logs suggest other threads are getting their
time-slices and the critical does not continue afterwards.'
This does not sound at all like an OS scheduling problem. It sounds much more like the 'critical thread' is getting blocked or has exited because of some exception.
Repetitive runs suggest that the critical thread stops in different
point of execution
sounds more exceptionny than blocky.
If I'm wrong, and your critical thread is getting preempted because there are more ready threads than cores, you should raise the priority of your critical thread so that it does not get preempted, (or just reduce the loading on the box:).
The only other possibility is that your thread is using a huge amount of data and you're getting a lot of page-faults. In this case, get more RAM, an SSD, or both!

Interrupting a thread while it is running; what is the impact of the next interruption?

Let's assume thread t1 is running (i.e. not in a sleep, wait or join state). Another thread t2 interrupts t1. The Javadoc says t1's interrupted status will be set.
Let's assume t1 falls into sleep, wait or join status later. What happens?
i) Is thread t1 automatically raised with an InterruptedException since it had an interrupted status?
Let's assume t1 is still into a sleep, wait or join state. Let's imagine t2 interrupts t1 again:
ii) Is thread t1 raised with an InterruptedExecution or does it need to clear its interruption status with a call to interrupted() first?
Is there an official Java position on this one? Thanks.
In the first case ("i"), yes, the sleeping thread will get popped out of its call to Thread#sleep() by way of an InterruptedException being thrown. At this point, the thread's status flag represented by Thread#isInterrupted() will be cleared; calling Thread#isInterrupted() would return false. Since the InterruptedException is in flight, the message has been sent to all transitive callers.
It's then the callers' responsibility to catch that exception and do one of two things:
either exit the current thread, or
call Thread#interrupt() on the current thread (that is, Thread.currentThread().interrupt())
When you say that thread "t1" is "still in a sleep, wait, or join state," the only way it could be so after its initial call to Thread#sleep() exited via InterruptedException is if it caught the exception, ignored it, and called on some blocking method like Thread.sleep() again before thread "t2" has a chance to interrupt it a second time.
If thread "t2" were to interrupt thread "t1" again while "t1" is currently blocked on an interruptible method call, "t1"'s call will again exit with an InterruptedException. Otherwise, the thread's interruption flag will be set for later detection.
Every time one calls Thread#interrupt(), the the interruption status of that target thread will be set to "true," meaning the thread has been interrupted since its interruption status was last cleared. The next time that the interrupted thread attempts to make a blocking call to an interruptible method, the thread's interruption status will be cleared and the method will throw InterruptedException.
Note that clearing the interruption status like that does not lose information so long as the clearing is immediately followed by throwing InterruptedException. A thrown InterruptedException is best interpreted as, "This thread had its interruption status set at some point prior, and now it's your responsibility to react and, usually, to warn subsequent callers of the intended interruption." You achieve the latter objective by calling Thread#interrupt() after catching InterruptedException, restoring the interruption status for others to see.
See the book Java Concurrency in Practice for a more authoritative description of this protocol.
Checking the interrupted state of a thread clears the state flag; that is to say, the code that raises an InterruptedException is clearing the state, as your own code that manually samples the state.

Categories

Resources