Reputation: 2678
In my program I have many threads in a working state, started in the method run or by calling other method from run. What is the method to stop these threads?
The threads are started as:
Runnable r = new Runnable() {
@Override
public void run() {
// do something...
}
};
new Thread(r,"Thread_1").start();
Another one may be like:
Runnable r = new Runnable() {
@Override
public void run() {
startThread(); // another method called
}
};
new Thread(r,"Thread_2").start();
What is the method of stopping thread_1
and thread_2
?
UPDATE
What I want is when I click on a button deactivate
3-4 threads working behind should get deactivated so that the user can again start those threads by again assigning a task.
Upvotes: 7
Views: 4305
Reputation: 1363
The trouble with setting a flag and having a thread periodically examine the flag to drive thread interruption is, what if your thread is invoking a long-running API method, or a blocking method, such as the put method on a full BlockingQueue that will never be dequeued because the thread that was to dequeue it has been shut down, or blocked reading from a socket that will likewise never be written to? In all such cases, none of these long-running invocations will ever stop to examine your flag, and your application may hang.
The proper way to interrupt a thread is to execute the Thread.interrupt() method on that thread instance, and in the running thread itself, you should examine Thread.currentThread().isInterrupted() periodically to determine if the thread should be interrupted, and of course catch InterruptedException and perform an orderly shutdown should it be thrown.
The advantage to this approach is that if your thread is invoking a long-running method, hopefully, that method will also check Thread.currentThread().isInterrupted() periodically, and will respond to the interruption request by doing an orderly shutdown and then propagating the InterruptedException. For example, BlockingQueue.put will indeed detect an interruption request issued by Thread.interrupt(). Sockets will not detect an interrupt request, but will respond to having the socket closed, something that can be done in a thread's overridden interrupt() method.
Since there's really no way to invoke the interrupt() method on an anonymous thread, you probably shouldn't use them for long-running tasks.
I recommend reading, "Java Concurrency in Practice". It's an excellent book, and chapter 7, "Cancellation and Shutdown" is devoted to this sort of thing. It explains it far better than I can.
Upvotes: 1
Reputation: 18578
As i understand, you want to know how to detect a particular anonymous thread and stop it.
You can try getCurrentThread()
method to detect the thread. Although using stop()
is not safe, it is deprecated.
Thread thread = Thread.getCurrentThread();
if(thread.getName() == "Thread_1" || thread.getName() == "Thread_2")
{
thread.stop();
}
Upvotes: 0
Reputation: 403581
Thread.stop()
is very dangerous, it's strongly recommended that you avoid it, for the reasons stated in the javadoc.
Try passing a message into the Runnable
, perhaps using something like this:
final AtomicBoolean terminate = new AtomicBoolean(false);
Runnable r = new Runnable() {
@Override
public void run() {
while (!terminate.get()) {
// do something...
}
}
};
new Thread(r,"Thread_1").start();
// some time later...
terminate.set(true);
You'd have to figure out a way to scope the variables to allow this to compile under your setup. Alternatively, extend Runnable
with your interface which has a cancel()
method (or whatever), which your anonymous classes have to implement, which does a similar sort of thing with the loop check flag.
interface CancellableRunnable extends Runnable {
void cancel();
}
CancellableRunnable r = new CancellableRunnable() {
private volatile terminate = false;
@Override
public void run() {
while (!terminate) {
// do something...
}
}
@Override
public void cancel() {
terminate = true;
}
}
new Thread(r,"Thread_1").start();
// some time later...
r.cancel();
Upvotes: 6
Reputation: 62459
If you want to forcefully abort them, you can call the stop()
method (not recommended). Just make sure you are not opening files, doing socket I/O, using locks etc.
A better approach would be to have a while loop testing a flag inside the run:
public void run() {
while(!stop) {
// work
}
}
And set stop
to true
when you want the thread to stop. Don't forget to make it volatile
.
Upvotes: 0
Reputation: 115378
Thread class has method stop()
introduced in java 1.0 and deprecated in java 1.1. This method still works and kills thread. So, you can stop all your threads if you want.
But this is very not recommended. The reason is described in javadoc of Thread.stop()
. So the best solution is to fix the implementation of your threads to make them exit correctly. But if it is not possible (e.g. if this is not your code) and you still need this very much use Thread.stop()
.
Upvotes: 1