Java: How to stop thread? [duplicate] - java

This question already has answers here:
How do you kill a Thread in Java?
(17 answers)
Closed 9 years ago.
Is there any way to stop another thread from OUTSIDE of the thread?
Like, if I ran a thread to run that thread and caused that thread to stop? Would it stop the other thread?
Is there a way to stop the thread from inside without a loop?
For example, If you are downloading ideally you would want to use a loop, and if I use a loop I wont be able to pause it until it reaches the end of the loop.

We don't stop or kill a thread rather we do Thread.currentThread().isInterrupted().
public class Task1 implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
................
................
................
................
}
}
}
in main we will do like this:
Thread t1 = new Thread(new Task1());
t1.start();
t1.interrupt();

You can create a boolean field and check it inside run:
public class Task implements Runnable {
private volatile boolean isRunning = true;
public void run() {
while (isRunning) {
//do work
}
}
public void kill() {
isRunning = false;
}
}
To stop it just call
task.kill();
This should work.

One possible way is to do something like this:
public class MyThread extends Thread {
#Override
public void run() {
while (!this.isInterrupted()) {
//
}
}
}
And when you want to stop your thread, just call a method interrupt():
myThread.interrupt();
Of course, this won't stop thread immediately, but in the following iteration of the loop above. In the case of downloading, you need to write a non-blocking code. It means, that you will attempt to read new data from the socket only for a limited amount of time. If there are no data available, it will just continue. It may be done using this method from the class Socket:
mySocket.setSoTimeout(50);
In this case, timeout is set up to 50 ms. After this time has gone and no data was read, it throws an SocketTimeoutException. This way, you may write iterative and non-blocking thread, which may be killed using the construction above.
It's not possible to kill thread in any other way and you've to implement such a behavior yourself. In past, Thread had some method (not sure if kill() or stop()) for this, but it's deprecated now. My experience is, that some implementations of JVM doesn't even contain that method currently.

The recommended way will be to build this into the thread. So no you can't (or rather shouldn't) kill the thread from outside.
Have the thread check infrequently if it is required to stop. (Instead of blocking on a socket until there is data. Use a timeout and every once in a while check if the user indicated wanting to stop)

JavaSun recomendation is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread to terminate.
You can that way kill the other process, and the current one afterwards.

Related

stop an infinite loop within a thread

Thread d = new Thread(new Runnable() {
#Override
public void run() {
while(true);
}
});
d.start();
How can I quit the infinite loop, without changing the code inside the method public void run(),
and without using d.stop(); (deprecated method).
P.S: I'd prefer publishing the whole exercise details I need to do. That's kinda the thing I need to dill with. They gave me a function which sometimes goes inside infinite loop, and I can't change that method.
How can I quit the infinite loop, without changing the code inside the method public void run(), and without using d.stop(); (deprecated method).
I assume this is some sort of academic or interview question. If you can't change the thread code then you can't add an interrupt or volatile boolean check. And you can't call .stop() (which is btw deprecated and never a good idea).
The only thing I can think of is to set the thread be a daemon thread.
Thread d = new Thread(new Runnable() { ... });
...
d.setDaemon(true);
d.start();
It needs to be set daemon before it is started. This is a hack but maybe within the framework of the question. This won't kill the thread immediately but if the last non-daemon thread exits then the thread will be killed by the JVM.
Of course you can also remove the .start() line but that seems outside the realm of the question. System.exit(0); would also bring down the JVM as #MattBall pointed out but that also seems like cheating.
Outside of killing the JVM running the thread, I don't see how you can quit the loop.
A better method would at minimum check for thread interruption:
Thread d = new Thread(new Runnable() {
#Override
public void run() {
while(!Thread.currentThread().isInterrupted());
};
d.start();
d.interrupt();
You can't. The only way to stop a thread asynchronously is the stop() method. But without that, you can't.
Without .stop() you need to change the code in the thread itself. see here here for some ideas.
Always avoid while(true). Try while(running). That condition should determine the life of the loop. Then when you set running = false, the life of the loop ends and subsequently the thread.

Java: Thread/task expiration after specified milliseconds

In Java is there a sane way to have a thread/task run continuously and then end after a specified run time (preferably without using several timers)?
For instance, if I have a TimerTask, there doesn't seem to be a way to schedule that task to end after a certain number of milliseconds or at a specific time with the Timer class.
Sure, I can schedule a task to repeat after a number of milliseconds, but what if I want it to end after one iteration? I have to run another timer within this scheduled task? I'm hoping for a more elegant answer than that.
The answer provided in this question could work, but it is definitely not what I had in mind.
Essentially, I'm looking for something similar to the AutoReset property on C#'s System.Timers.Timer class
You can use an ExecutorService, grab the Future you get and .cancel() it after the time you want:
final Future<Whatever> f = executor.submit(...);
TimeUnit.SECONDS.sleep(xxx);
f.cancel(true);
Or you can have two services: one which executes, another which uses a ScheduledExecutorService for the cancellation.
NOTE: TimerTask depends on the system time, use a ScheduledExecutorService instead.
Simply create another thread and have it time it for when it wants the other thread to stop:
class ThreadTimer implements Runnable {
public void run()
{
Thread.sleep(3000);
MainThread.stopThread();
}
}
class MainThread implements Runnable {
public boolean running = true;
public void run()
{
// thread running code
if(!running)
return;
}
public static void stopThread()
{
running = false;
}
}
Where 3000 is the amount of time in milliseconds from when you want the thread to stop.
Since Thread.stop() is deprecated in Java, the next best way is to only execute the thread if a boolean is set to true. When you call to stop the thread, you're setting that boolean to false, making the code in the thread not run.
Because the void run() doesn't repeat itself and only executes once, if you set the boolean to false, it simply returns run() and halts the thread's execution.
If your task is running in a loop, you can check the current time on each iteration, and terminate the loop if enough time has passed.
Or, if your task involves sleeps, you can set a timer on another thread to call Thread.interrupt on the task.
The only other option would be to set a timer on another thread to call Thread.stop. However, Thread.stop has been deprecated, and there's no safe way to stop a general thread in Java.

is this the correct way to 'stop' a thread gracefully?

instead of continuous checking of variable inside a loop:
class Tester {
public static void main() {
Try t = new Try();
Thread.sleep(10); //wait for 10 milliseconds
t.interrupt(); // 'interrupt' i.e stop the thread
}
}
public class Try extends Thread {
public void interrupt() {
//perform all cleanup code here
this.stop();
/*stop() is unsafe .but if we peform all cleanup code above it should be okay ???. since thread is calling stop itself?? */
}
}
In order to perform interrupt in a good manner you should poll for the "interrupted()" method inside the thread that is being interrupted.
Just be aware that calling interrupted() method resets the interruption flag (that is set when calling interrupt()).
I guess the bottom line is that you have to continuously poll inside the thread in order to perform a graceful interruption.
You should never ever call .stop() on a Thread, period. It's not enough for the thread to perform its own cleanup. Since calling .stop() immediately releases all monitors, other threads may see shared data in an inconsistent state which may result in almost impossible to track errors.
Use Thread.interrupt() method instead of Thread.stop(). In the interrupted thread you can catch the InterruptedException and do any cleanup required.
A similar questions has already been asked here, you can find a code sample there too.

How to kill a thread which has a while(true)?

I am trying to close all my thread in my threadpool.
Usually I try:
while(!Thread.currentThread().isInterrupted()) {...
To close the while loop...
But I have one Thread which only consists about
while(!Thread.currentThread().isInterrupted()) {//which is true
This is how I close the threads:
pool.shutdownNow();
So how would you close such a Thread?
You can add a volatile boolean flag.
public class Worker implements Runnable {
volatile boolean cancel = false;
#Override
public void run() {
while (!cancel) {
// Do Something here
}
}
public void cancel() {
cancel = true;
}
}
Now you can just call
worker.cancel();
Update:
From Java doc of shutdownNow()
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
here are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
So either you will have to define your interruption policy by preserving the interrupts
catch (InterruptedException ie) {
// Preserve interrupt status
Thread.currentThread().interrupt();
}
Instead of that you might use a self created flag as condition for the while loop.
public class MyClass implements Runnable
{
private volatile boolean running = true;
public void stopRunning()
{
running = false;
}
public void run()
{
while (running)
{
}
// shutdown stuff here
}
}
Now, to stop it, just call:
myClassObject.stopRunning();
This will let the code finish normally.
If you have implemented this as you have described, it should just work.
When you call pool.shutdownNow() it is supposed to interrupt all worker threads that are currently active. Assuming that the application specific run() methods check the interrupted flag and terminate themselves when they find it set, your threads should shutdown.
There is really no need to add a different mechanism using an ad hoc cancel flag ... or some such.
Incidentally, there are a couple reasons why interrupt() is better than ad hoc cancellation:
Standard APIs like ExecutorService use it.
Various low-level API methods like sleep, wait, join and some I/O methods are sensitive to it.
If you are using a java.util.concurrent ExecutorService implementation, then it will definitely send an interrupt signal to all the threads in its thread pool. The problem with your rogue task may be that the loop doesn't in fact iterate, but blocks somewhere within, so the interrupted status is not getting checked at all.
Yet another problem you may have: the while loop runs some code that catches InterruptedException without handling it properly, effectively swallowing the interrupt signal. This is a common coding mistake and in most cases due to the ugly truth that InterruptedException is checked.

How should I terminate a looped sub-thread in Java?

I need to do some clean up work when I am going to terminate a looped thread. Such as saving a buffer so I can continue later.
PseudoCode:
private class CalculatePI(Byte[] resume) implements Runnable{
public void Run(){
while(true){
resume=resumeCalculating(resume);
}
}
}
Thread calculator= new Thread(new CalculatePI(Byte[] resume));
Thread.sleep(200);
//And now I want to kill calculator
So what's the best way implement this?
Use a flag: But the problem is what if resumeCalculating() takes (EDIT: a long time) forever to end?
Put an exception into calculator, how?
Can I use event listeners or something? I thought they were used for GUIs
Just stop it? And Class Thread includes some kind of deconstructor that will be called when the thread is terminated and I could do the processing there?
EDIT by Owner:
I know I can use a flag. But consider this:
public void Run(){
while(true){
resume=calculate_stepone(resume); //takes one minute
resume=calculate_steptwo(resume); //takes two minutes
resume=calculate_stepthree(resume); //takes three minutes
resume=calculate_steplast(resume); //takes four minutes
}
}
Is putting a if(flag) saveResultsAndExit(); between every line practical or pretty?
I just want to throw away the half-processed results, and save the previous results.
The proper way to stop a thread is to interrupt it.
If the task running in the thread is performing IO or is using sleep then it will receive the signal (InterruptedException at that point); else the task should regularly poll to see if its interrupted.
Lets adapt the original poster's psuedocode:
private class CalculatePI(Byte[] resume) implements Runnable{
public void Run(){
while(!Thread.interrupted()) { //###
resume=resumeCalculating(resume);
}
}
}
Thread calculator= new Thread(new CalculatePI(Byte[] resume));
calculator.run(); //###
//...
//And now I want to kill calculator
calculator.interrupt(); //### sends the signal
//...
calculator.join(); //### actually waits for it to finish
Answer to 1.: You can process the abort flag in resumeCalculating() too.
It is probably best to use a flag, wait for a while for the thread to end, and if it hasn't (resumeCalculating hasn't returned) kill the thread manually. It is probably best not to involve too much thread based logic in resumeCalculating, it really depends on how it is implemented as to how easy it is to abort halfway through an operation.
Design your program so that resumeCalculating does NOT take forever to continue. Also, synchronize access to your flag.

Categories

Resources