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.
Related
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
What will happen if we access a thread which was stopped using stop() method.
UserThread t = new UserThread();
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
System.out.println(t.getState());
Anyhow stop() method is deprecated in java8, but need the output for above. Is it possible to access the thread which was stopped means in terminated state?
Thanks in advance.
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock
all the monitors that it has locked. (The monitors are unlocked as the
ThreadDeath exception propagates up the stack.) If any of the objects
previously protected by these monitors were in an inconsistent state,
other threads may now view these objects in an inconsistent state.
Such objects are said to be damaged. When threads operate on damaged
objects, arbitrary behavior can result. This behavior may be subtle
and difficult to detect, or it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath kills threads silently; thus, the
user has no warning that his program may be corrupted. The corruption
can manifest itself at any time after the actual damage occurs, even
hours or days in the future.
What should I use instead of Thread.stop?
Most uses of stop should be replaced by code that simply modifies some
variable to indicate that the target thread should stop running. The
target thread should check this variable regularly, and return from
its run method in an orderly fashion if the variable indicates that it
is to stop running. To ensure prompt communication of the
stop-request, the variable must be volatile (or access to the variable
must be synchronized).
For example, suppose your applet contains the following start, stop and run methods:
private Thread blinker;
public void start() {
blinker = new Thread(this);
blinker.start();
}
public void stop() {
blinker.stop(); // UNSAFE!
}
public void run() {
while (true) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
You can avoid the use of Thread.stop by replacing the applet's stop and run methods with:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
If you are interested in seeing what is the state of a thread after you call stop you can suppress the deprecation warning by adding #SuppressWarnings("deprecation") before your test class definition.
For instance try the following code:
#SuppressWarnings("deprecation")
class test {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {}
}
}
};
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
try {
Thread.sleep(1000); // wait for stop to take effect
}catch(Exception e) {}
System.out.println(t.getState());
}
}
Spoiler alert: the status is TERMINATED
Its advised not use stop() method in Thread class since this is deprecated.
If you want to abort the thread execution use interrupt()
class IntThread extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("Didn't Interrupt me !!!");
}catch(InterruptedException e){
throw new RuntimeException("Thread interrupted..."+e);
}
}
public static void main(String args[]){
IntThread t1=new IntThread();
t1.start();
try{
t1.interrupt();
}catch(Exception e){System.out.println("Exception handled "+e);}
}
}
You can refer link for more details about interrupt.
In my run() method of my Thread class, I am calling a never ending function.
I need the thread to run only for a specific duration.
Am not able to control the thread once its started, Is their any way to destroy it?
I have tried yield(), sleep(), etc...
PS - I cannot change the never ending function
From oracle Java Docs:
public void run(){
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
}
Your thread should check interrupted condition after each loop to see if it was interrupted. If you are calling a method that just does while(true){} then I am afraid there is no way interrupting it and stop() MUST never be called on a thread.
It is the programmers responsibility to make a long running method responsive to interrupts.
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html answers all your questions.. particularly section What should I use instead of Thread.stop?
Hope it helps
This could be too much, but this is how I would solve it, if you do not want to mess with Interrupt.
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadTest test = new ThreadTest();
test.go();
}
void go() throws InterruptedException{
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new LongRunnable());
if(!service.awaitTermination(1000, TimeUnit.MILLISECONDS)){
System.out.println("Not finished within interval");
service.shutdownNow();
}
}
}
class LongRunnable implements Runnable {
public void run(){
try{
//Simultate some work
Thread.sleep(2000);
} catch(Exception e){
e.printStackTrace();
}
}
}
Basically you are wrapping your runnable in a ExecutorServie and if it's not finished within the interval, you basically kill it - send the interruption to it.
I have been looking for ways to kill a thread and it appears this is the most popular approach
public class UsingFlagToShutdownThread extends Thread {
private boolean running = true;
public void run() {
while (running) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread");
}
public void shutdown() {
running = false;
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.shutdown();
}
}
However, if in the while loop we spawn another another object which gets populated with data (say a gui that is running and updating) then how do we call back - especially considering this method might have been called several times so we have many threads with while (running) then changing the flag for one would change it for everyone?
thanks
One approach with these problems is to have a Monitor class which handles all the threads. It can start all necessary threads (possibly at different times/when necessary) and once you want to shutdown you can call a shutdown method there which interrupt all (or some) of the threads.
Also, actually calling a Threads interrupt() method is generally a nicer approach as then it will get out of blocking actions that throw InterruptedException (wait/sleep for example). Then it will set a flag that is already there in Threads (which can be checked with isInterrupted() or checked and cleared with interrupted(). For example the following code can replace your current code:
public class UsingFlagToShutdownThread extends Thread {
public void run() {
while (!isInterrupted()) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { interrupt(); }
}
System.out.println("Shutting down thread");
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
i added a utlility class which essentially had a static map and methods.
the map was of type Long id, Thread thread. I added two methods one to add to the map and one to stop the thread via the use of interrupt. This method took the id as a parameter.
I also changed my loop logic from while true, too while ! isInterrupted. Is this approach ok or is this bad programming style/convention
thanks
I'm writing an application that spawns multiple concurrent tasks. I'm using a thread pool to implement that.
It may happen that an event occurs that renders the computations being done in the tasks invalid. In that case, I would like to stop the currently running tasks, and start new ones.
My problem: How do I stop the currently running tasks? The solution I implemented is to store a reference to the task thread and call interrupt() on this thread. In demo code:
public class Task implements Runnable {
private String name;
private Thread runThread;
public Task(String name) {
super();
this.name = name;
}
#Override
public void run() {
runThread = Thread.currentThread();
System.out.println("Starting thread " + name);
while (true) {
try {
Thread.sleep(4000);
System.out.println("Hello from thread " + name);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
}
}
public void stop() {
runThread.interrupt();
}
public String getName() {
return name;
}
}
And the main method is:
public static void main(String args[]) {
executorService = Executors.newFixedThreadPool(2);
Task t1 = new Task("Task1");
Task t2 = new Task("Task2");
executorService.execute(t1);
executorService.execute(t2);
executorService.execute(new Task("Task3"));
executorService.execute(new Task("Task4"));
try {
Thread.sleep(12000);
t1.stop();
System.err.println("Stopped thread " + t1.getName());
Thread.sleep(8000);
t2.stop();
System.err.println("Stopped thread " + t2.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Is this a good solution, or is there a better way to stop a running thread in a thread pool?
You can stop it by holding a reference to that future
Future<?> future = exec.submit( new Runnable() {
while (true){
try{
obj.wait();
} catch(InterruptedException e){
System.out.println("interrupted");
return;
}
}
});
future.cancel(true);
boolean is for - may interrupt if running.
I tested out and got an interrupted exception from that thread.
If you have cachedThreadPool you may want to double check that you catch the exception in your runnable, and then don't set back the flag interrupted, because your thread will run another future, if you set interrupt, the other queue future may not run.
The idea behind your approach is one of the several correct solutions. Dealing with InterruptedException gives a great rundown on how you should use the interrupt mechanism. This mechanism is mainly useful when you are long computations. One other thing to keep in mind is that it is possible for other libraries to spoil your interrupt mechanism by not doing what the guide says (not resetting the interrupt state when they haven't handled it etc).
Do note that your Task class isn't thread-safe. You could be stopping the task before saving the currentThread, which would give a NullPointerException.
A much simpler approach is to set a volatile boolean variable running and instead of a while(true) loop doing a while(running) approach (this is however much more general).
Another thing to look at is the FutureTask mechanism, as this already has a canceling mechanism that uses the interrupt mechanism.
In your overridden run() method you loop forever with while(true). The standard behaviour would be to have a boolean runIndicator which the run() method sets to true when it starts, and your loop should then be while(runIndicator). Your stop() method should simple set runIndicator = false so the next iteration of the loop will fall out.
executorService.shutdown() and executorService.shutdownNow() should be used to shutdown the thread pool to gracefully exiting the application. See ExecutorService.
See Qwerky's answer for ending the currently running thread.