I am having a real hard time finding a way to start, stop, and restart a thread in Java.
Specifically, I have a class Task (currently implements Runnable) in a file Task.java. My main application needs to be able to START this task on a thread, STOP (kill) the thread when it needs to, and sometimes KILL & RESTART the thread...
My first attempt was with ExecutorService but I can't seem to find a way for it restart a task. When I use .shutdownnow() any future call to .execute() fails because the ExecutorService is "shutdown"...
So, how could I accomplish this?
Once a thread stops you cannot restart it. However, there is nothing stopping you from creating and starting a new thread.
Option 1: Create a new thread rather than trying to restart.
Option 2: Instead of letting the thread stop, have it wait and then when it receives notification you can allow it to do work again. This way the thread never stops and will never need to be restarted.
Edit based on comment:
To "kill" the thread you can do something like the following.
yourThread.setIsTerminating(true); // tell the thread to stop
yourThread.join(); // wait for the thread to stop
Review java.lang.Thread.
To start or restart (once a thread is stopped, you can't restart that same thread, but it doesn't matter; just create a new Thread instance):
// Create your Runnable instance
Task task = new Task(...);
// Start a thread and run your Runnable
Thread t = new Thread(task);
To stop it, have a method on your Task instance that sets a flag to tell the run method to exit; returning from run exits the thread. If your calling code needs to know the thread really has stopped before it returns, you can use join:
// Tell Task to stop
task.setStopFlag(true);
// Wait for it to do so
t.join();
Regarding restarting: Even though a Thread can't be restarted, you can reuse your Runnable instance with a new thread if it has state and such you want to keep; that comes to the same thing. Just make sure your Runnable is designed to allow multiple calls to run.
It is impossible to terminate a thread unless the code running in that thread checks for and allows termination.
You said: "Sadly I must kill/restart it ... I don't have complete control over the contents of the thread and for my situation it requires a restart"
If the contents of the thread does not allow for termination of its exectuion then you can not terminate that thread.
In your post you said: "My first attempt was with ExecutorService but I can't seem to find a way for it restart a task. When I use .shutdownnow()..."
If you look at the source of "shutdownnow" it just runs through and interrupts the currently running threads. This will not stop their execution unless the code in those threads checks to see if it has been ineterrupted and, if so, stops execution itself. So shutdownnow is probably not doing what you think.
Let me illustrate what I mean when I say that the contents of the thread must allow for that thread to be terminated:
myExecutor.execute(new Runnable() {
public void run() {
while (true) {
System.out.println("running");
}
}
});
myExecutor.shutdownnow();
That thread will continue to run forever, even though shutdownnow was called, because it never checks to see if it has been terminated or not. This thread, however, will shut down:
myExecutor.execute(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
System.out.println("running");
}
}
});
myExecutor.shutdownnow();
Since this thread checks to see whether or not it has been interrupted / shut down / terminated.
So if you want a thread that you can shut down, you need to make sure it checks to see if it has been interrupted. If you want a thread that you can "shut down" and "restart" you can make a runnable that can take new tasks as was mentioned before.
Why can you not shut down a running thread? Well I actually lied, you can call "yourThread.stop()" but why is this a bad idea? The thread could be in a synchronized (or other critical section, but we will limit ourselves to setions guarded by the syncrhonized key word here) section of code when you stop it. synch blocks are supposed to be executed in their entirity and only by one thread before being accessed by some other thread. If you stop a thread in the middle of a synch block, the protection put into place by the synch block is invalidated and your program will get into an unknown state. Developers make put stuff in synch blocks to keep things in synch, if you use threadInstance.stop() you destroy the meaning of synchronize, what the developer of that code was trying to accomplish and how the developer of that code expected his synchronized blocks to behave.
You can't restart a thread so your best option is to save the current state of the object at the time the thread was stopped and when operations need to continue on that object you can recreate that object using the saved and then start the new thread.
These two articles Swing Worker and Concurrency may help you determine the best solution for your problem.
As stated by Taylor L, you can't just "stop" a thread (by calling a simple method) due to the fact that it could leave your system in an unstable state as the external calling thread may not know what is going on inside your thread.
With this said, the best way to "stop" a thread is to have the thread keep an eye on itself and to have it know and understand when it should stop.
If your task is performing some kind of action in a loop there is a way to pause/restart processing, but I think it would have to be outside what the Thread API currently offers. If its a single shot process I am not aware of any way to suspend/restart without running into API that has been deprecated or is no longer allowed.
As for looped processes, the easiest way I could think of is that the code that spawns the Task instantiates a ReentrantLock and passes it to the task, as well as keeping a reference itself. Every time the Task enters its loop it attempts a lock on the ReentrantLock instance and when the loop completes it should unlock. You may want to encapsulate all this try/finally, making sure you let go of the lock at the end of the loop, even if an exception is thrown.
If you want to pause the task simply attempt a lock from the main code (since you kept a reference handy). What this will do is wait for the loop to complete and not let it start another iteration (since the main thread is holding a lock). To restart the thread simply unlock from the main code, this will allow the task to resume its loops.
To permanently stop the thread I would use the normal API or leave a flag in the Task and a setter for the flag (something like stopImmediately). When the loop encountered a true value for this flag it stops processing and completes the run method.
Sometimes if a Thread was started and it loaded a downside dynamic class which is processing with lots of Thread/currentThread sleep while ignoring interrupted Exception catch(es), one interrupt might not be enough to completely exit execution.
In that case, we can supply these loop-based interrupts:
while(th.isAlive()){
log.trace("Still processing Internally; Sending Interrupt;");
th.interrupt();
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
There's a difference between pausing a thread and stopping/killing it. If stopping for you mean killing the thread, then a restart simply means creating a new thread and launching.
There are methods for killing threads from a different thread (e.g., your spawner), but they are unsafe in general. It might be safer if your thread constantly checks some flag to see if it should continue (I assume there is some loop in your thread), and have the external "controller" change the state of that flag.
You can see a little more in:
http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
May I ask why you want to kill the thread and restart it? Why not just have it wait until its services are needed again? Java has synchronization mechanisms exactly for that purpose. The thread will be sleeping until the controller notifies it to continue executing.
You can start a thread like:
Thread thread=new Thread(new Runnable() {
#Override
public void run() {
try {
//Do you task
}catch (Exception ex){
ex.printStackTrace();}
}
});
thread.start();
To stop a Thread:
thread.join();//it will kill you thread
//if you want to know whether your thread is alive or dead you can use
System.out.println("Thread is "+thread.isAlive());
Its advisable to create a new thread rather than restarting it.
Related
is there any kind of Runnable, Callable or Thread with capability of stopping it in any duration of time?
I wrote something like this
public class ThreadRunner {
private ExecutorService threadPoolExecutor;
ThreadRunner() {
threadPoolExecutor = Executors.newSingleThreadExecutor();
}
public void startThread(String endPoint, ProgressBar progressBar) {
Runnable task = () -> {
// some code which saves images from URL (1230 images) and updates progress bar
};
threadPoolExecutor.execute(task);
}
public void stopThread() {
threadPoolExecutor.shutdownNow();
}
}
Thread runs correctly, images are being saved, progress bar being updated, but when I want to stop thread (or maybe even pause process of saving if possible) by calling ThreadRunner class's method - nothing happens.
Am I doing something wrong - or most likely - what am I doing wrong?
is there any kind of Runnable, Callable or Thread with capability of stopping it in any duration of time?
You can implement such a thing yourself, but there is no generic support available for it, unless you count the long-deprecated Thread.stop() methods. Under no circumstances should you use those methods, but do read their API docs for a discussion of why they are deprecated and what you can do instead. You can find a longer-form version of the discussion in Java's technical notes.
The bottom line is that the computation you want to be able to stop needs to periodically check some shared variable or built-in condition to determine whether to do so. You arrange for that variable to be set when you want the thread to stop, and if you need to block until it does stop then you join() it. Under some circumstances, it can be helpful to interrupt() the thread to get it to check the variable (or being interrupted can itself serve as the termination condition). The user-facing end of this can be wrapped up in a method.
In any case, an ExecutorService cannot give you a handle on this. Requesting such a service to shut down will prevent it from dispatching any more tasks, but there is no safe, general-purpose mechanism by which it could force a premature shutdown of tasks that are already running.
Once started, a thread will run until Runnable.run() exits. Due to several issues you should never use Thread.stop() or Thread.interrupt().
Instead, you will have to implement your own logic for exit/pause. A few suggestions:
For stopping the thread, you can make a boolean variable shouldExit. In your thread, check this variable every now and then, and just do "return" or break the for/while loop when it becomes true. Setting this variable from another thread should now make the downloader exit. If necessary, you should surround access to this variable with synchronized block as to prevent any race conditions.
For pausing the thread, you can use a similar approach. When you set a certain variable to true (e.g. isPaused), make the thread react by going into an Object.sleep(). This way, it won't consume any CPU during sleep. You can then use Object.notify() from another thread to "kick" the sleeping thread out ouf sleep. You will need a synchronized block here, too.
This question already has answers here:
Do java threads get deleted when they finish
(3 answers)
Closed 7 years ago.
I want to know if a thread in java closes itself when run method ends.
I mean, I have a new thread declaration:
new Thread(new SubmitDataOnBackground(handler.getIDValue(), data, this.context)).start();
And then, in SubmitDataOnBackground I have this run method:
public void run() {
SubmitDataHandler submit = new SubmitDataHandler(ID, data, this.context);
submit.buildAndSubmitData();
}
After buildandSubmitData finishes, does the thread close itself or I have to add any code somewhere?
I am not sure if I am leaving a new thread opened each time I call this method or it is ok.
My application is a server so it will never ends because it is active the whole time. I just want to know the amount of threads is not outnumbered because it just creates new ones without closing the others when finish.
Threads close themselves after the run method has been called. Read this for further information https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
EDIT: If you want to avoid this behaviour, I recommend using ThreadPools.
Yes, a thread finishes when run() method execution ends. You can read more on threads and concurency in general here
One tip here - when using multiple threads that are started and finished all the time, it is a good idea to use a thread pool. That is because creating a thread is quite a heavy operation.
Threads are terminated after finishing their jobs (when the execution of run() ends). If you want to check, use isAlive().
Yes, threads are terminated after finishing their specified jobs (sequence of instructions) in run() method.
However, the thread object that has been created still exists, allowing you call it again with Thread.start() to create a new Thread.
If you want to be sure that your thread run method ends before continuing doing something more, try to use the method Thread.join() in the same place where you are working with threads.
Read this for further information about that:
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join%28%29
In order to actually make a Thread stop itself, the process is quite simple. All you need to do is simply let the run method run out and return.
public void run(){
// implement your code
// Just about to return and the Thread will then stop soon after
}
Note that the thread will not necessarily be declared finished immediately after the run method has finished, as the Java Virtual Machine (JVM) still needs to finish it off in the background, but it should terminate completely soon after.
In other words, when a normal Thread (also referred to as a user Thread) is created, it is expected that it will complete its work and not shut down permanetly. The JVM will not terminate until all user Threads have finished, or until a call is made to the System.exit() method, which terminates the JVM abruptly.
EDIT: System.exit() does not stop the JVM abruptly, it executes all the shutdown hooks first. Runtime.getRuntime().halt() stops the JVM without any further processing.
Suppose during my running I would like to shutdown a single thread gracefully!
I don't want to use Thread.stop() nor Thread.destroy() due to their unsafe behavior.
Note: I'm familiar with using ExecutorService.shutdown() option.
But I would like to know the other way to implement.
The standard way to stop a thread is to call thread.interrupt();. To make it work, you need to make sure you thread responds to interruption, for example:
Thread t = new Thread(new Runnable() { public void run {
while(!Thread.currentThread().isInterrupted()) {
//your code here
}
}});
t.start();
t.interrupt();
This only works if the condition is checked regularly. Note that you can delegate the interruption mechanism to interruptible methods (typically I/O, blocking queues, sleep/wait provide methods that can block until they are interrupted).
Note: In this example, you can also use:
while(!interrupted()) {
//your code here
}
interrupted() does the same thing as Thread.currentThread().isInterrupted() except that the interrupted flag is reset. Since it is your thread, it does not matter.
You could have isStopped()flag in your code. And the running thread should regularly check this flag to see if it should stop. Note that stopping a thread gracefully requires the running code to be written in a way that allows stopping.
You can take a look at this question for some more detailed answers
You have to make the run() method of the thread terminate for some reason. How you achieve this depends on what the thread does.
If the thread is looping, you can stop it by raising a flag (checked by the condition of the loop).
If the thread is waiting over a Socket or any other stream, just close the stream.
If the thread is blocked on a call that can throw an InterruptedException, you can interrupt() the thread and ignore the exception.
If the thread is consuming the elements of a blocking queue, use the poison pill method, which means putting on the queue an element that just means "stop looping".
If you have a loop inside your run() method of your Thread then one option would be that your loop checks for the value of a flag on every iteration.
You can set the flag from outside the code, such as your thread would stop executing before starting the next iteration.
As many others I have a problem killing my thread without using stop().
I have tried to use volatile on a variable with a while loop in my threads run() routine.
The problem is as far as I can see, that the while loop only checks the variable before every turn. The complex routine Im running takes a long time, and because of that the thread is not terminated immediately.
The thread I want to terminate is a routine that connects to another server and it uses a looooong time. And I want to have an abort button for this. (Terminating the thread). I'll try to explane with some code.
class MyConnectClass{
Thread conThread;
volitile boolean threadTerminator = false;
..some code with connect and abort button..
public void actionPerformed(ActionEvent e) {
String btnName = e.getActionCommand();
if(btnName.equalsIgnoreCase("terminate")){
threadTerminator = true;
conThread.interrupt();
System.out.println("#INFO# USER ABORTED CURRENT OPERATION!");
}else if(btnName.equalsIgnoreCase("connectToServer")){
conThread = new Thread() {
public void run() {
while(threadTerminator == false){
doComplexConnect(); //Uses a loooong time
}
}
}
conThread.start();
}
}
}
How can I kill my "connection" thread instantly?
Thanks.
Java abandoned the stop() approach in Threads a while back because killing a Thread ungracefully caused huge problems in the JVM. From the Javadoc for stop():
Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many 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. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.
In most cases, it is up to you to check the threadTerminator var whenever it is safe for you to terminate, and handle the thread exit gracefully. See http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
If you are doing long I/O, you may be in trouble. Some I/O operations throw an InterruptedException, in which case, you can interrupt the thread, and, if you were in that I/O, that exception will be thrown more or less instantly, and you can abort and cleanup the thread. For this reason, interrupting a thread is preferable to using a special custom threadTerminator variable - it's much more standard. In you main code outside of the I/O, check for interrupted() or isInterrupted() periodically (instead of threadTerminator == false).
If you are doing I/O that doesn't throw InterruptedException, sometimes you can close the Socket or similar, and catch the IOException. And sometimes you are stuck.
Why don't you interrupt the thread and just move on, letting it hang until it finishes? The user could initiate a different action (thread) while the old thread finishes gracefully (which, from what I see you are pretty much doing already btw)
The downside of this that you have trouble when the user starts clicking "connectToServer" a lot (many threads), or when the threads fail to terminate (hanged threads). But maybe it's sufficient for your purpose?
Edit:
It would be simple to implement a mechanism that prevents spawning a new conthread unless "it's good to go" (e.g., use a semaphore).
The tricky part will be deciding whether it's good to open a new connection. You could ask the original thread (I.e. have a isalive() method), or the party you are trying to connect to. Or you could go for a timeout solution. For example, you could let conthread update a timestamp and decide it's dead if the timestamp isn't updated for 1 min etc. The most generally applicable solution would probably be the timeout solution.
I'm trying to implement a sort of interrupt process into my java program so that if an operation takes longer than 5 minutes, i can kill it.
Is there any sort of generic way I can do this? I'm using an external API to carry out very processor intensive calculations and it already multithreads the process so can I still use the executor class to do this?
-edit-
Ended up solving it by using a bash script wrapper function. It kills the PID after a timeout.
It's considered unsafe to kill or forcefully stop a Thread because it may leave the program in an undetermined state, which will later cause a crash or other more serious problem. Instead, you should design your worker thread to periodically check the interrupt flag via Thread#isInterrupted or Thread#interrupted and exit if it is set. Then, using another thread, you can signal to the worker thread that it should stop by calling interrupt() on the worker thread, which will result in the worker thread detecting the interrupt or possibly receiving an InterruptedException if it is blocking inside your code or the third party code.
Depending on how your thread is coded (ie. whether it would properly terminate when interrupted), you could use the provided Thread.join(millis) or Thread.join(mills, nanos) method calls.
Something like this:
Thread myThread
// ... start myThread
myThread.join(300000); // 5mins in millis
if (myThread.isAlive()) {
myThread.interrupt();
}
Inside the thread itself, you would want to ensure that you .yield() at relevant points and properly handle an InterruptedException to allow this kind of logic to work.
Of course this is an "ideal" kinda situation - if the thread is blocked due to some outside process, and cannot handle the .interrupt(), then it will not work very well.
HTH