program-o-steve
program-o-steve

Reputation: 2678

How can I stop threads created with an anonymous class?

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

Answers (5)

Lyle Z
Lyle Z

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

dku.rajkumar
dku.rajkumar

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

skaffman
skaffman

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

Tudor
Tudor

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

AlexR
AlexR

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

Related Questions