java - 执行器服务设置标志以停止线程

标签 java multithreading threadpool executorservice

我正在运行简单的线程,其运行方法如下

public run()
while(!stopFlag){
   // print something Line 1
   // print something Line 2
   // print something Line 3
   // print something Line 4
}

如果我通过 ExecutorService viz 运行此线程

ExecutorService exs = Executors.newFixedThreadPool(5);
exs.execute(new MyThread));

我停止ExecutorService

exs.shutdown();

但这不会停止线程,因为标志未设置为 false。在 another question related to same topic我被要求正确处理调用 exs.shutdown() 时引起的 InterruptedException。 但在这种情况下,我没有执行任何可能引发 InterruptedException 的操作。

处理这种情况的标准方法是什么?

进一步问题 Sabir 给出的答案是“如果你的可运行程序对中断响应不好,除了关闭 JVM 之外,没有什么可以阻止它。”。这似乎是我的情况。

但是如何引入InterruptedException的处理;如果我没有调用任何抛出中断异常的方法?

最佳答案

如果即使该标志保持为 true,您也愿意关闭线程,则应该使用 - ExecutorService.shutdownNow() 方法,而不是 ExecutorService.shutdown()

引用自 Java 文档,

关闭()

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.

This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

shutdownNow()

Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.

This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.

对于标准方式,我将引用来自ExecutorService接口(interface)的JDK示例,

使用示例

Here is a sketch of a network service in which threads in a thread pool service incoming requests. It uses the preconfigured Executors.newFixedThreadPool factory method:    class NetworkService implements Runnable {    private final ServerSocket serverSocket;    private final ExecutorService pool;

   public NetworkService(int port, int poolSize)
       throws IOException {
     serverSocket = new ServerSocket(port);
     pool = Executors.newFixedThreadPool(poolSize);    }

   public void run() { // run the service
     try {
       for (;;) {
         pool.execute(new Handler(serverSocket.accept()));
       }
     } catch (IOException ex) {
       pool.shutdown();
     }    }  }

 class Handler implements Runnable {    private final Socket socket;   Handler(Socket socket) { this.socket = socket; }    public void run() {
     // read and service request on socket    }  }} The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks:    void shutdownAndAwaitTermination(ExecutorService pool) {    pool.shutdown(); // Disable new tasks from being submitted    try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }    } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();    }  }}

请注意,即使使用 shutdownNow() 也无法保证。

编辑:如果我将您的 while(!stopFlag) 更改为 while(!Thread.currentThread().isInterrupted()) 那么具有条件循环的线程可以使用 shutdownNow() 关闭,但不能使用 shutdown() 关闭,因此线程会使用 shutdownNow() 中断。我使用的是 JDK8 和 Windows 8.1。我确实必须在主线程中进行 sleep ,以便服务有时间来设置服务并启动可运行程序。线程启动,进入 while,然后在调用 shutdownNow() 时停止。我没有通过 shutdown() 得到这种行为,即线程永远不会脱离 while 循环。因此,应该有让可运行对象负责中断的方法,无论是通过检查标志还是处理异常。如果您的可运行程序不能很好地响应中断,除了关闭 JVM 之外,没有什么可以阻止它。

展示了一种好方法here

关于java - 执行器服务设置标志以停止线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43993505/

相关文章:

java - 检索和设置 IntelliJ IDEA 插件开发的拆分窗口设置

java - 将列表信息传递给新 Activity

java - 在将扩展类初始化为接口(interface)时调用扩展类的方法

java - QtWebkit 多线程

java - 创建比请求更多的线程

multithreading - Scala Future[T] 是否在内部阻塞? Scala Future 内部会发生什么?

java - Spring Boot 应用程序无法运行 - spring.resources.cache-period 未绑定(bind)

java - Android中线程的合理使用

.net - 调试 I/O 完成线程泄漏

java - 运行程序60分钟,每个线程使用不同的ID