how to stop a thread with thread interrupt method - java

I am trying to learn thread interrupt and how to make a thread terminate without calling stop.
public class Test implements Runnable{
static Thread threadTest=null;
public static void main(String args[]){
System.out.println("Hello i am main thread");
Test thread= new Test();
threadTest= new Thread(thread);
threadTest.start();
}
private static void exitThread() {
threadTest.interrupt();
}
#Override
public void run() {
boolean run = true;
while (run) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
run = false;
}
}
}
}
Output
Hello i am main thread
Sleeping
Processing
Sleeping
I am unable to understand why Sleeping is printed second time and interrupted exception is thrown second time rather than first time.I have checked posts where volatile keyword is used to stop a thread in java.but i am unable to understand how that will be used in this scenario as thread gets stopped with interrupt.

In order to see the thread being interrupted instead of entering the sleep method a second time, change the while loop test in the run method to check the interrupt flag:
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
The thread will sleep, then set its own interrupt flag, then check the flag and terminate. InterruptedException would be thrown by the Thread#sleep method only if the thread was sleeping while the interrupt flag was set.
Your local boolean variable is not needed. If Thread#sleep throws an InterruptedException (which it won't in this example because the thread checks the interrupted flag and leaves the while loop) then the interrupt flag is cleared, restoring it in the catch block allows the while test to see that the thread was interrupted.
In real programs the thread would be interrupted from another thread, there's no reason for a thread to interrupt itself (it can just return instead).

Calling Thread.interrupt() just sets a flag for the thread. It doesn't do anything else. Only blocking methods (those usually declare throws InterruptedException) respond to that flag being set (by throwing). The flag is sticky in that it remains set until its cleared.
So the first call to the sleep method just runs normally (the interrupted flag isn't set yet). After that your code does nothing that acts on the interrupted status, until the second loop iteration where the sleep call detects the interrupted status and throws the exception.
You can use Thread.interrupted() or Thread.isInterrupted() to check the interrupted status at any time (beware that interrupted() also clears the interrupted status if it was set).

here you creating another thread Test class but "main" has its own thread , so the new thread you created is interpreted .
Here in this code you are interrupting the new created thread Thread-0 not main thread,when you execute this code you are making thread to sleep before it enters the method exitThread() ,so it is displaying the processing, but if you try to put thread sleep after you enter exitthread() you will have your answer
Like in this code:
public class Test implements Runnable {
public boolean run = true;
#Override
public void run() {
while (run) {
try {
System.out.println("Sleeping...");
exitThread();
Thread.sleep(10000);
System.out.println("Processing...");
} catch (InterruptedException e) {
System.out.println("Thread intreputted " + e);
run = false;
}
}
}
private void exitThread() {
Thread.currentThread().interrupt();
if (Thread.currentThread().isInterrupted())
System.out.println(Thread.currentThread().getName()
+ " is intreputted");
else
System.out.println("alive");
}
public static void main(String[] args) {
System.out.println("hi I am current thread------>"
+ Thread.currentThread().getName());
Test test = new Test();
Thread thread = new Thread(test);
thread.start();
}
}
Hope it will be helpfull

Related

Threads logic in Java

I'm trying to resolve a university exercise. The class AImpl has a method ma(B b) that creates and runs two threads. These threads have to call mb1() and mb2() (they are simple methods that just print a text, so I didn't include them). The calling thread should then wait for mb1() to terminate before finishing.
My logic is:
The first thread enters and after finishing the execution of b.mb1() starts to wait() on the current object, releasing the mutex. Then the second thread runs and it does the same. When they are both waiting, the calling thread calls notifyAll() on the object, waking both of them. They execute b.mb2() and then terminate.
The problem is that when the first thread starts waiting with object.wait(), the control flow doesn't return on the calling thread and the program enters in a deadlock.
Where is my logic flawed?
public class AImpl{
public static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
BImpl b = new BImpl();
AImpl.ma(b);
}
public static void ma(B b) throws InterruptedException {
Thread thread = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
Thread thread1 = new Thread() {
#Override
public void run() {
b.mb1();
synchronized(object){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
b.mb2();
System.out.println("Thread finished");
}
};
thread.run();
thread1.run();
synchronized(object){
object.notifyAll();
}
System.out.println("Program finished.");
}
}
The notify/notifyAll methods tell the scheduler to notify one/all of the threads currently waiting on the lock that notify or notifyAll was called on. But if a thread hasn't started waiting yet then it doesn't get notified.
The solution is to introduce a condition variable that keeps wait from being called if the notifying has happened already. Define it in the same scope as your lock:
public static volatile boolean ready = false;
Then use it to guard the wait block, like this:
while (!ready) {
object.wait();
}
The code calling notify/notifyAll needs to set the variable (it doesn't matter what order you do it in because the notification doesn't happen until the lock is released):
synchronized (object) {
ready = true;
object.notifyAll();
}
What happens:
If the waiting thread gets to the waiting part before the notifying thread does its notifying, then the waiting thread finds ready is false, so it enters the wait method, releases the lock, and stays there. Then the notifying thread changes the flag to true and wakes up the waiting thread, which can leave the wait, reacquire the lock, and then leave the loop now that the flag is set.
But if the notifying thread does its notify before the other thread waits, that's ok, because the ready flag now prevents the thread from entering the wait, it can skip over it.
Further reading: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

precise behaviour of interrupt() method with respective to thread states in java

I have read the post below
What does java.lang.Thread.interrupt() do? but i have not been able to get it completely right
I quote from #Mike_q answer to above question as below
Thread.interrupt() sets the interrupted status/flag of the target thread. Then code running in that target thread MAY poll the interrupted status and handle it appropriately. Some methods that block such as Object.wait() may consume the interrupted status immediately and throw an appropriate exception (usually InterruptedException)
It says while object is in WAITING it can consume interrupted status, so what happens when it is BLOCKED state waiting for object's lock ... ?
i have experimented below with that scenario and code is
at X: t2 is blocked
public class interruptsyc
{
static Object resource = new Object();
public static void main(String []args)
{
System.out.println("started main");
Thread1 t1=new Thread1("thread 1");
t1.start();
delay(1000);
Thread2 t2 =new Thread2("thread 2");
t2.start();
delay(1000);
t2.interrupt(); // X: at this point t2 is in blocked state waiting for resource's lock
System.out.println(t2.getName()+t2.interrupted());
delay(1000);
System.out.println("end main");
}
static void delay(long n)
{
try
{
Thread.sleep(n);
}
catch(InterruptedException ex)
{
System.out.println(Thread.currentThread().getName()+Thread.interrupted());
ex.printStackTrace();
}
}
static class Thread1 extends Thread{
Thread1(String name)
{
setName(name);
}
public void run()
{
synchronized(resource)
{
System.out.println("start 1");
delay(6000);
System.out.println("end 1");
}
}
}
static class Thread2 extends Thread{
Thread2(String name )
{
setName(name);
}
public void run()
{
synchronized(resource)
{
System.out.println("start 2");
delay(2000);
System.out.println("end 2");
}
}
}
}
and output has below
started main
start 1
false
end main
end 1
start 2
thread 2false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at interruptsyc.delay(interruptsyc.java:25)
at interruptsyc$Thread2.run(interruptsyc.java:59)
end 2
it seems that InterruptedException has been called ,when sleep method is called later... why is that ...?
again what is polling i didn't quite understand from what is said here
Polling occurs via the Thread.interrupted() method which returns the current thread's interrupted status AND clears that interrupt flag. Usually the thread might then do something such as throw InterruptedException.
again whenever i called Thread2.interrupted() method in above code it returned false (when i called just after t2.interrupt and in catch block)
it seems that InterruptedException has been called ,when sleep method is called later... why is that ...?
Because blocking/sleeping methods don't block immediately. They first check if the thread has been interrupted, and if it has been, they throw an InterruptedException immediately, in order for the thread to stop ASAP.
whenever i called Thread2.interrupted() method in above code it returned false
Because when blocking/sleeping methods throw an InterruptedException, they also clear the interrupt flag.
This is in the javadoc of Thread.sleep():
Throws InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

Single Thread.interrupt() interrupts more than once

I created MyTask which has 3 things to do inside run(). I try to interrupt() the thread which holds MyTask instance. Unfortunately once it is interrupted, it ends and only string First task is printed on the console.
public class MyTask implements Runnable {
private volatile Thread thread;
#Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
If I add Thread.sleep(10) in the run() it starts to work correctly and it prints First task, Second task and finally Third task on the console.
The question is: Whydoes Thread.interrupts() work correctly only if I add sleep()?
public class MyTask implements Runnable {
private volatile Thread thread;
#Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
To quote from Interrupts:
When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
Meaning: Change your code from thread.isInterrupted() to Thread.interrupted() and try again.
The sleep() in between your loops will clear that flag as well by throwing InterruptedException immediately (as the current Thread has been interrupted)
Have a look at the Javadoc on Thread.sleep(long)
Throws: InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
Hence, adding that sleep as well catching (and ingoring) any exception will result in the observed behavior.
Example:
Without the sleep():
Thread starts with interrupted = false thus 1st loop runs
Thread gets interrupted, i.e. now interrupted = true
1st loop checks interrupted and doesn't run (again)
2nd loop checks interrupted and doesn't run at all
3rd loop checks interrupted and doesn't run at all
finished
With the sleep()
thread starts with interrupted = false
loop 1:
while condition is checked and body is executed since interrupted = false
thread gets interrupted, i.e. now interrupted = true
while condition is checked but this time interrupted = true so the loop ends
sleep() is called and since the thread has been interrupted the exception is thrown and interrupted = false again
the exception is caught (and ignored) and thus execution is continued normally
step 2 is repeated for loops 2 and 3
finished

How to restart thread without using Thread.stop()?

I have a client-server application that runs the receive method to run in a separate thread. Thread is given some time to finish the job and the thread will be checked for the status.
There are occasions when the receive method will be blocked due to packet or ACK loss. If that happens, how can I stop the thread and start it again the next attempt?
As we all know, Thread.stop() is deprecated.
You can't restart a Java thread at all, with or without Thread.stop().
You have to create a new one.
You can however reuse a Runnable.
You can use interrupts to send to the thread and handle them to do a retry. Here is a sample that will start a thread that will not quit until the boolean done is set. However i'm interrupting the thread from a main thread to make it start over.
public class Runner implements Runnable {
private boolean done;
#Override
public void run() {
while (!done) {
try {
doSomeLongRunningStuff();
} catch (InterruptedException e) {
System.out.println("Interrupted..");
}
}
}
private void doSomeLongRunningStuff() throws InterruptedException {
System.out.println("Starting ... ");
Thread.sleep(300);
System.out.println("Still going ... ");
Thread.sleep(300);
done = true;
System.out.println("Done");
}
public static void main(final String[] args) throws InterruptedException {
final Thread t = new Thread(new Runner());
t.start();
Thread.sleep(500);
t.interrupt();
Thread.sleep(500);
t.interrupt();
}
}
Whether you can do it this way or not depends on what you are calling. Your framework doing the TCP connection may or may not support interrupting.
We should not restart a thread which is not valid , once thread has comepleted its execution.

How can I kill a thread? without using stop();

Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
The alternative to calling stop is to use interrupt to signal to the thread that you want it to finish what it's doing. (This assumes the thread you want to stop is well-behaved, if it ignores InterruptedExceptions by eating them immediately after they are thrown and doesn't check the interrupted status then you are back to using stop().)
Here's some code I wrote as an answer to a threading question here, it's an example of how thread interruption works:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Some things to be aware of:
Interrupting causes sleep() and wait() to immediately throw, otherwise you are stuck waiting for the sleep time to pass.
Note that there is no need for a separate boolean flag.
The thread being stopped cooperates by checking the interrupted status and catching InterruptedExceptions outside the while loop (using it to exit the loop). Interruption is one place where it's ok to use an exception for flow control, that is the whole point of it.
Setting interrupt on the current thread in the catch block is technically best-practice but is overkill for this example, because there is nothing else that needs the interrupt flag set.
Some observations about the posted code:
The posted example is incomplete, but putting a reference to the current thread in an instance variable seems like a bad idea. It will get initialized to whatever thread is creating the object, not to the thread executing the run method. If the same Runnable instance is executed on more than one thread then the instance variable won't reflect the right thread most of the time.
The check for whether the thread is alive is necessarily always going to result in true (unless there's an error where the currentThread instance variable is referencing the wrong thread), Thread#isAlive is false only after the thread has finished executing, it doesn't return false just because it's been interrupted.
Calling Thread#interrupted will result in clearing the interrupt flag, and makes no sense here, especially since the return value is discarded. The point of calling Thread#interrupted is to test the state of the interrupted flag and then clear it, it's a convenience method used by things that throw InterruptedException.
Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Good way to do it would be to use a boolean flag to signal the thread.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Create a MyRunnable instance called myrunnable, wrap it in a new Thread instance and start the instance. When you want to flag the thread to stop, set myrunnable.stopThread = true. This way, it doesn't get stopped in the middle of something, only where we expect it to get stopped.

Categories

Resources