停止java.util.concurrent.Executor任务的方法

时间:2014-11-18 04:48:20

标签: java multithreading concurrency

我想知道有没有办法以优雅的方式停止java.util.concurrent.Executor任务,或者我们应该使用java.util.concurrent.ExecutorService,它是java.util.concurrent.Executor之上的一层(java。 util.concurrent.ExecutorService有关闭的API)?

package com.example;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class ExecutorTaskExample {

public static void main(String[] args) {
    Executor executor = Executors.newFixedThreadPool(5);

    for(int i=0; i<10; i++){
        ThreadTask task = new ThreadTask();
        task.setTaskName("task_"+i);
        executor.execute(task);
    }
    System.out.println("Program Completed");
}

}

class ThreadTask implements Runnable{
private String taskName;

@Override
public void run(){
    System.out.println("Task: "+this.getTaskName()+"processed by "+Thread.currentThread().getName());
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public String getTaskName() {
    return taskName;
}

public void setTaskName(String taskName) {
    this.taskName = taskName;
}   

}

2 个答案:

答案 0 :(得分:2)

在Java中外部停止线程没有“优雅”的方法。

您需要不时检查代码“shouldStop”标志并自行退出。

这没有什么不同,无论你使用什么API(缺少一个我不会链接的严重弃用的Thread方法)。

ExecutorService#shutdown不会对当前正在运行的任务执行任何操作。如果还有任务,它甚至会继续启动排队任务。它将停止接受新的。

ExecutorService#shutdownNow会更加激进,因为它会向运行的线程发送interrupt()(但仍然需要运行的应用程序代码来处理它)。

FWIW,你的Thread#sleep会被这样打断。

答案 1 :(得分:1)

java.util.concurrent.Executor没有任何特定方法来终止任务。

您可以将java.util.concurrent.ExecutorService用于此目的。

ExecutorService executor = Executors.newFixedThreadPool(5);

for(int i=0; i<10; i++){
    ThreadTask task = new ThreadTask();
    task.setTaskName("task_"+i);
    executor.execute(task);

    if (some condition) {
        executor.shutdown();
    }
}

但是对于executor.shutdown()方法,doc说明了

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.

<强>更新

我试过下面的代码。我认为这就是你要找的东西。

public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(5);
    List<Future<?>> list = new ArrayList<Future<?>>();

    for (int i = 0; i < 5; i++) {
        ThreadTask task = new ThreadTask();
        task.setTaskName("task_" + i);
        Future<?> future = executor.submit(task);
        list.add(future);
    }
    for (Future<?> f : list) {
        if (!f.isDone()) {
            System.out.println("Running thread terminating");
            f.cancel(true);
        }
    }
    for (Future<?> f : list) {
        if (f.isDone()) {
            System.out.println("Running thread terminated");
        }
    }
    executor.shutdown();
    System.out.println("Program Completed");
}