Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to stop a thread in a threadpool

Tags:

java

I'm writing an application that spawns multiple concurrent tasks. I'm using a thread pool to implement that.

It may happen that an event occurs that renders the computations being done in the tasks invalid. In that case, I would like to stop the currently running tasks, and start new ones.

My problem: How do I stop the currently running tasks? The solution I implemented is to store a reference to the task thread and call interrupt() on this thread. In 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 is:

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 a running thread in a thread pool?

like image 925
user456045 Avatar asked Sep 23 '10 11:09

user456045


1 Answers

The idea behind your approach is one of the several correct solutions. Dealing with InterruptedException gives a great rundown on how you should use the interrupt mechanism. This mechanism is mainly useful when you are long computations. One other thing to keep in mind is that it is possible for other libraries to spoil your interrupt mechanism by not doing what the guide says (not resetting the interrupt state when they haven't handled it etc).

Do note that your Task class isn't thread-safe. You could be stopping the task before saving the currentThread, which would give a NullPointerException.

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

Another thing to look at is the FutureTask mechanism, as this already has a canceling mechanism that uses the interrupt mechanism.

like image 174
Thirler Avatar answered Nov 15 '22 00:11

Thirler