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

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

Stack Overflow用户
提问于 2017-05-15 21: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-15 22: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 02: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

复制
相关文章
javascript将html实体转回
有时候我们可能需要向html中传递html代码。但是因为我们的后台框架使用了laravel。所以我们在赋值的时候就会变成:
魔王卷子
2019/05/31
9780
短实体,长句实体抽取
“半指针-半标注”方法实体的抽取器,基于苏神的三元组抽取方法改造,这里取消了三元组抽取模型中对s的抽取,直接抽取实体并做分类(相当于直接抽取p和o)。改造后的实体抽取方法不仅可以运用于短实体的抽取,也可以运用到长句实体的抽取。
机器学习AI算法工程
2020/09/14
1.9K0
EF实体中的修改
思路:先从ObjectContext取出实体,然后将前台传过来的DTO属性对应赋值到我们的实体上,然后调用ObjectContext的保证修改方法。
跟着阿笨一起玩NET
2018/09/19
1.1K0
springboot 根据实体类生成数据库中表BaseEntity(公共实体)配置文件application.yml 子类实体:
1.标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
用户5899361
2020/12/07
5K0
SpringBoot 使用注解将配置文件自动映射到属性和实体类
1. 属性单独映射 ---- 1. Controller上面配置 @PropertySource({"classpath:application.properties"}) 2. 对要配置的属性添加注解 @Value("${web.file.path}") private String filePath; 3. 接口测试 @GetMapping("/test/property-source") public Object testPropertySource() { System.out.print
山海散人
2021/03/03
1.3K0
nginx设置header如果没有值
map 指令是由 ngx_http_map_module 模块提供的,默认情况下安装 nginx 都会安装该模块。
十毛
2022/08/23
1.4K0
nginx设置header如果没有值
[NewLife.XCode]实体工厂(拦截处理实体操作)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。
大石头
2019/07/02
1K0
实体识别(1) -实体识别任务简介
命名实体识别(Named Entity Recognition,简称NER) , 是指识别文本中具有特定意义的词(实体),主要包括人名、地名、机构名、专有名词等等,并把我们需要识别的词在文本序列中标注出来。
致Great
2023/08/25
4910
实体识别(1) -实体识别任务简介
Apple Card实体卡曝光,只有logo没有卡号
在今年3月的春季发布会上,苹果在Apple Pay的基础上推出了信用卡“Apple Card”,就在近日,国外知名数码产品爆料者Ben Geskin在推特上展示了苹果实体信用卡的真面目,从图片上可以看出这款信用卡的设计非常简约,卡面上除了logo就是EMV芯片。
镁客网
2019/05/16
7900
JS魔法堂:再识ASCII实体、符号实体和字符实体
一、前言                                            相信大家都熟悉通过字符实体 &nbsp; 来实现多个连续空格的输入吧!本文打算对三类HTML实体及JS相关操作作进一步的整理和小结,若有纰漏请大家指正,谢谢。 二、初识HTML实体                                                                    由于HTML中某些字符是预留的(如>和<等),若要在进行HTML解析出来后能正确显示预留字符,则需要
^_^肥仔John
2018/01/18
2.2K0
实体-联系图(ER图)_实体关系图
我们通常用实体、联系和属性这三个概念来理解现实问题,因此ER模型比较接近人的思维方式。此外,ER模型用简单的图形符号表达系统分析员对问题域的理解,不熟悉计算机技术的用户也能理解它,因此,ER模型可以作为用户与分析员之间有效的交流工具。
全栈程序员站长
2022/09/29
2.3K0
实体-联系图(ER图)_实体关系图
python实现命名实体识别指标(实体级别)
{'ALBUM': [(18, 3)], 'SINGER': [(11, 3)], 'SONG': [(2, 3), (6, 3)], 'TAG': [(23, 3)]}
西西嘛呦
2020/11/12
1.3K0
将实体光盘制作成光盘映像iso文件
春节假期整理历史物件时发现一些书籍的光盘,虽然买了多年但一直没有看过,因为自己在用的电脑都没有光驱。正好老爸的电脑是带光驱的,想着趁过节把这些光盘的内容读取出来存在NAS上方便后续使用。 使用UltraISO软件直接“制作光盘映像文件”就可以将光盘的内容制作成iso文件,便于保存在磁盘等介质上。基本最长的也就是10分钟左右搞定。
Alfred Zhao
2023/02/10
2K0
HTML 字符实体
在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签。
用户8442333
2021/08/21
1.7K0
HTML字符实体
刚刚在修改文件的时候,空格怎么都打不上,后来反应过来得使用html字符实体,为了方便自己查找,便有了这篇文章
用砖头敲代码
2022/06/08
1.4K0
组合实体模式
组合实体模式(Composite Entity Pattern)用在 EJB 持久化机制中。一个组合实体是一个 EJB 实体 bean,代表了对象的图解。当更新一个组合实体时,内部依赖对象 beans 会自动更新,因为它们是由 EJB 实体 bean 管理的。以下是组合实体 bean 的参与者。
Java架构师必看
2020/04/13
4980
JPA实体类中的注解
@Entity   标注于实体类上,通常和@Table是结合使用的,代表是该类是实体类 @Table   标注于实体类上,表示该类映射到数据库中的表,没有指定名称的话就表示与数据库中表名为该类的简单类名的表名相对应,如果是逆向生成表的话就会以简单类名作为表名   如果指定名称,例如@Table(name="tb_user"),就表示映射到数据库中的tb_userz这个表; @Id   标注于属性上,通常是在get方法上,也可以在属性的声明上。   用于表示该属性作为ID主键 @GeneratedValue
二十三年蝉
2018/03/29
3.9K0
EntityFramework附加实体
//0.0创建修改的 实体对象 Models.BlogArticle model = new BlogArticle(); model.AId = 12; model.ATitle = "新的数据"; model.AContent = "新的数据~~~~~"; //0.1添加到EF管理容器中,并获取 实体对象 的伪包装类对象 DbEntityEntry<Models.BlogArticle> entry = db.Entry<Models.BlogArticle>(model); //**如果使用 En
liulun
2018/01/12
7570
实体识别(2) -命名实体识别实践CRF
CRF,英文全称为Conditional Random Field, 中文名为条件随机场,是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫(Markov)随机场。
致Great
2022/03/30
1.7K0
实体识别(2) -命名实体识别实践CRF
选择块参照中嵌套的实体
在利用ObjectARX进行CAD二次开发时,如何选择块参照中嵌套的实体,并进行进行下一步操作?这个问题的难点是:如何判断用户选中的实体到底是块参照里面的非嵌套对象实体?还是块参照中嵌套的块参照的实体?本文利用全局函数acedNEnsSelP解决了这个问题,并可实现:如果用户选择块参照中嵌套的实体,直接视为用户选择了这个嵌套的块参照,效果如图。
用户3519280
2023/07/31
2651

相似问题

无法用python连接到Server

12

用python中的connectorx连接MS SQL Server

216

无法用python连接到Azure Server

20

SQL Server SELECT with READONLY子句

40

用Streamlit编写连接python和Server的函数?

218
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档