发布
社区首页 >问答首页 >Executor Service设置标志以停止线程

Executor Service设置标志以停止线程
EN

Stack Overflow用户
提问于 2017-05-16 05:57:34
回答 2查看 2.5K关注 0票数 2

我正在运行简单的thread,该方法如下所示

代码语言:javascript
代码运行次数:0
复制
public run()
while(!stopFlag){
   // print something Line 1
   // print something Line 2
   // print something Line 3
   // print something Line 4
}

如果我在ExecutorService viz中运行这个线程

代码语言:javascript
代码运行次数:0
复制
ExecutorService exs = Executors.newFixedThreadPool(5);
exs.execute(new MyThread));

我阻止了ExecutorService

代码语言:javascript
代码运行次数:0
复制
exs.shutdown();

但是这并不会停止线程,因为标志没有设置为false。在另一个与同一主题有关的问题中,我被要求正确处理InterruptedException,这是在调用exs.shutdown()时引起的。但在这种情况下,我不做任何可以抛出InterruptedException的操作。

处理这类案件的标准方法是什么?

进一步问了沙比尔的答案:“如果你的可运行程序对中断没有很好的响应,除了关闭JVM之外,什么也不能阻止它。".This似乎就是我的情况。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-16 06:56:58

如果您愿意关闭您的线程,即使该标志仍然为真,则应使用- ExecutorService.shutdownNow()方法而不是ExecutorService.shutdown()

引用Java文档,

shutdown()

启动有序关机,执行以前提交的任务,但不接受任何新任务。如果已经关闭,则调用没有其他效果。 此方法不等待以前提交的任务完成执行。使用awaitTermination来完成这个任务。

shutdownNow()

尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。 此方法不等待主动执行任务终止。使用awaitTermination来完成这个任务。 除了尽力停止处理积极执行的任务之外,没有任何保证。例如,典型的实现将通过Thread.interrupt取消,因此任何无法响应中断的任务都可能永远不会终止。

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

使用示例

代码语言:javascript
代码运行次数:0
复制
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和Windows8.1。我必须在主线程中放置一个睡眠,这样服务才能有时间设置服务并启动可运行的。线程启动,然后进入,然后在调用shutdownNow()时停止。我不理解shutdown()的这种行为,即线程永远不会从while循环中出来。因此,让您的运行表负责中断的方法应该存在,要么检查标志,要么处理异常。如果您的runnable对中断没有很好的响应,那么除了关闭JVM之外,什么也不能阻止它。

这里展示了一个很好的方法

票数 2
EN

Stack Overflow用户

发布于 2017-05-16 10:46:05

好吧,从你的问题中,我假设你正试图优雅地关闭这个过程。为了做到这一点,您需要注册一个shutdownHook来实现它。这里有一个实现它的示例代码。

代码语言:javascript
代码运行次数:0
复制
package com.example;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadManager {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        Runtime.getRuntime().addShutdownHook(new Thread(){
            MyThread myThread = null;
            @Override
            public void run(){
                System.out.println("Shutting down....");
                this.myThread.stopProcess();
            }
            public Thread setMyThread(MyThread myThread){
                this.myThread=myThread;
                return this;
            }
        }.setMyThread(myThread));
        ExecutorService exs = Executors.newFixedThreadPool(5);
        myThread.setName("User");
        exs.execute(myThread);
        exs.shutdownNow();
    }
}

在MyThread.java中会出现以下情况:-

代码语言:javascript
代码运行次数:0
复制
package com.example;

public class MyThread extends Thread{
    private boolean stopFlag;

    @Override
    public void run(){
        while(!stopFlag){
           System.out.println(this.getName());
        }
    }
    public void stopProcess(){
        this.stopFlag=true;
    }
}

现在,如果您使用此代码生成一个jar文件,并在Linux服务器中运行该文件以查看其工作方式,那么请遵循以下附加步骤

代码语言:javascript
代码运行次数:0
复制
Step 1> nohup java -jar MyThread.jar &

按ctrl+c以存在,现在使用以下命令查找pid

代码语言:javascript
代码运行次数:0
复制
Step 2> ps -ef| grep MyThread.jar

一旦得到pid,就执行以下命令以优雅地停止

代码语言:javascript
代码运行次数:0
复制
Step 3>kill -TERM <Your PID>

当您检查nohub.out文件时,输出如下所示

代码语言:javascript
代码运行次数:0
复制
User
User
.
.
.
User
Shutting down....
User
.
.

记住,如果您试图使用杀死-9关闭,您将永远不会看到Shutting down....消息。

@沙比尔已经讨论了shutdownshutdownNow之间的区别。但是,我永远不会建议您在线程运行时使用interrupt调用。这可能会导致实时环境中的内存泄漏。

Upadte 1:-

代码语言:javascript
代码运行次数:0
复制
public static void main(String[] args) {
    MyThread myThreads[] = new MyThread[5];
    ExecutorService exs = Executors.newFixedThreadPool(5);
    for(int i=0;i<5;++i){
        MyThread myThread = new MyThread();
        myThread.setName("User "+i);
        exs.execute(myThread);
        myThreads[i] = myThread;
    }
    Runtime.getRuntime().addShutdownHook(new Thread(){
        MyThread myThreads[] = null;
        @Override
        public void run(){
            System.out.println("Shutting down....");
            for(MyThread myThread:myThreads){
                myThread.stopProcess();
            }
        }
        public Thread setMyThread(MyThread[] myThreads){
            this.myThreads=myThreads;
            return this;
        }
    }.setMyThread(myThreads));
    exs.shutdownNow();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43993505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档