How to stop thread in threadpool

I am writing an application that spawns several simultaneous tasks. I use a thread pool to implement this.

It may happen that an event occurs that makes the calculations performed in tasks invalid. In this case, I would like to stop the current tasks and start new ones.

My problem: how to stop current tasks? The solution I implemented is to keep a reference to the task thread and call interrupt() on that thread. In the 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:

 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 the current thread in the thread pool?

+6
java
source share
4 answers

The idea behind your approach is one of several correct solutions. Working with InterruptedException gives a great overview of how you should use the interrupt mechanism. This mechanism is mainly useful for lengthy calculations. Another thing to keep in mind is that other libraries can spoil your interrupt mechanism without doing what the guide says (without reloading the interrupt state when they don't handle it, etc.).

Please note that your Task class is not thread safe. You could stop the task before saving currentThread , which would give a NullPointerException.

. A simpler approach is to set the variable volatile boolean running and instead of a while(true) while(running) that executes the while(running) approach (this, however, is much more general).

Another thing worth paying attention to is the FutureTask mechanism, since it already has a cancellation mechanism that uses the interrupt mechanism.

+3
source share

In your overridden run() method, you loop forever with while(true) . The standard behavior would be to have a boolean runIndicator , which the run() method sets to true when it starts, and your loop should be while(runIndicator) . Your stop() method should have a simple set of runIndicator = false , so the next iteration of the loop will fail.

+2
source share

You can stop him by holding a link to this future.

  Future<?> future = exec.submit( new Runnable() { while (true){ try{ obj.wait(); }catch(InterruptedException e){ System.out.println("interrupted"); return; } }); future.cancel(true); 

boolean for - may be interrupted at startup.

I tested and received an interrupted exception from this thread.

If you have cachedThreadPool, you can double check that you will catch an exception in your runnable, and then do not turn off the flag interrupted because your thread will start another future, if you set an interrupt, another future of the queue may not work.

+2
source share

executorService.shutdown () and executorService.shutdownNow () should be used to disable the thread pool to gracefully exit the application. See ExecutorService .

See Qwerky's answer for completing the current thread.

+1
source share

All Articles