JAVA线程执行中断方式和ElasticSearch未捕获异常的处理方式

JAVA线程执行中断方式

Java中只能通过协作的方式取消

  • 第一种是通过标志位实现,假设有个计算所有素数的任务,每次计算前检查下是否取消的标志位,如果为true则退出计算。调用方想要取消任务的话,则将标志位设为true。但这种方法无法再计算的过程中取消任务,像是一些阻塞调用无法被取消

  • 第二种是中断,用于通过协作机制停止线程继续执行任务,原理是向进程发送中断请求将标记线程为Interrupted,线程会在下一个合适的时刻停止运行,阻塞的库方法例如Thread.sleep Object.wait 都会响应中断,抛出InterruptedException意味着阻塞操作因为中断结束,但不能保证响应速度。

    通常任务不会在自己拥有的线程执行,而是在某个服务的线程池中执行,因此任务应该保存阻塞状态,使得线程能处理中断。这就是库函数抛出InterruptedException的原因。同时任务也不能对线程处理中断的策略做任何假设。

    有两种处理中断的方法,千万不要catch掉异常什么也不做,除非你拥有该线程

    • 向外抛出InterruptedException
    • 调用 Thread.currentThread().interrupt();恢复中断状态

    例如在向线程池提交runnable执行时,runnable调用了阻塞库函数则需要写处理中断的逻辑,逻辑中要使用上面处理中断的两种方法之一,因为线程池会处理线程遇到阻塞,将线程从可用线程列表删除,统计审计信息等操作

    final void runWorker(Worker w) {Thread wt = Thread.currentThread();Runnable task = w.firstTask;w.firstTask = null;w.unlock(); // allow interruptsboolean completedAbruptly = true;try {while (task != null || (task = getTask()) != null) {w.lock();try {beforeExecute(wt, task);Throwable thrown = null;try {task.run(); // 执行runnable} catch (RuntimeException x) {thrown = x; throw x;} catch (Error x) {thrown = x; throw x;} catch (Throwable x) {thrown = x; throw new Error(x);} finally {afterExecute(task, thrown);}} finally {task = null;w.completedTasks++;w.unlock();}}completedAbruptly = false;} finally {processWorkerExit(w, completedAbruptly); // 处理InteruptException}}
    private void processWorkerExit(Worker w, boolean completedAbruptly) {if (completedAbruptly) // If abrupt, then workerCount wasn't adjusteddecrementWorkerCount();final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {completedTaskCount += w.completedTasks;workers.remove(w);} finally {mainLock.unlock();}tryTerminate();int c = ctl.get();if (runStateLessThan(c, STOP)) {if (!completedAbruptly) {int min = allowCoreThreadTimeOut ? 0 : corePoolSize;if (min == 0 && ! workQueue.isEmpty())min = 1;if (workerCountOf(c) >= min)return; // replacement not needed}addWorker(null, false);}}
    

还有一种方法是使用future来中断任务执行,使用submit.cancel(true),内部也是利用了Thread.interrupt

ExecutorService executor = Executors.newFixedThreadPool(1);final Future<?> submit = executor.submit(() -> {});try {final Object o = submit.get(10, TimeUnit.MILLISECONDS);} catch (TimeoutException e) {}finally {submit.cancel(true); // 正常得到结果后再cancel也无影响}

未捕获异常的处理方式

线程因为异常或者error退出后,会向System.error输出堆栈,但线上程序一般通过日志来排查问题而不是控制台输出。Java支持配置Thread.UncaughtExceptionHandler处理这种未被捕获的Throwable,程序最好自己实现该接口,至少将异常堆栈输出到日志中,下面是ES实现的Thread.UncaughtExceptionHandler(去掉了一些细节),ES将异常信息输出到了日志文件。

class ElasticsearchUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {private static final Logger logger = LogManager.getLogger(ElasticsearchUncaughtExceptionHandler.class);@Overridepublic void uncaughtException(Thread thread, Throwable t) {if (isFatalUncaught(t)) {onFatalUncaught(thread.getName(), t);} else {onNonFatalUncaught(thread.getName(), t);}}static boolean isFatalUncaught(Throwable e) {return e instanceof Error;}void onFatalUncaught(final String threadName, final Throwable t) {final String message = "fatal error in thread [" + threadName + "], exiting";logger.error(message, t);Terminal.DEFAULT.errorPrintln(message);t.printStackTrace(Terminal.DEFAULT.getErrorWriter());// Without a final flush, the stacktrace may not be shown before ES exitsTerminal.DEFAULT.flush();}void onNonFatalUncaught(final String threadName, final Throwable t) {final String message = "uncaught exception in thread [" + threadName + "]";logger.error(message, t);Terminal.DEFAULT.errorPrintln(message);t.printStackTrace(Terminal.DEFAULT.getErrorWriter());// Without a final flush, the stacktrace may not be shown if ES goes on to exitTerminal.DEFAULT.flush();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/657574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 系统相关的命令

参考资料 Linux之chmod使用【linux】chmod命令详细用法 目录 一. 系统用户相关1.1 查看当前访问的主机和用户1.2 切换用户1.2.1 设置root用户密码1.2.2 普通用户和root用户切换 1.4 系统状态1.4.1 vmstat 查看当前系统的状态1.4.2 history 查看系统中输入过的命令 二. 系统文件…

React18-列表数据实现用户删除、批量删除

用户删除、批量删除接口 删除、批量删除接口 接口地址 POST/users/delete请求参数 {userIds: [] }参数为数组&#xff0c;删除和批量删除共用 功能介绍 单个删除 删除按钮绑定事件&#xff0c;点击显示弹框确认。 // 删除 const handleDel (values: DataType) > {//…

图扑 HT UI 5.0 全新升级,开箱即用!

为顺应数字时代的不断发展&#xff0c;图扑 HT UI 5.0 在原有功能强大的界面组件库的基础上进行了全面升级&#xff0c;融入了更先进的技术、创新的设计理念以及更加智能的功能。HT UI 5.0 使用户体验更为直观、个性化&#xff0c;并在性能、稳定性和安全性等方面达到新的高度。…

githacker安装详细教程,linux添加环境变量详细教程(见标题三)

笔者是ctf小白&#xff0c;这两天也是遇到.git泄露的题目&#xff0c;需要工具来解决问题&#xff0c;在下载和使用的过程中也是遇到很多问题&#xff0c;写此篇记录经验&#xff0c;以供学习 在本篇标题三中有详细介绍了Linux系统添加环境变量的操作教程&#xff0c;以供学习 …

TensorFlow2实战-系列教程6:猫狗识别3------迁移学习

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 猫狗识别1 数据增强 猫狗识别2------数据增强 猫狗识别3------迁移学习 1、迁移学习 …

TensorFlow2实战-系列教程15:Resnet实战3

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 Resnet实战1 Resnet实战2 Resnet实战3 7、训练脚本train.py解读------配置训练参数 …

解读4篇混合类型文件Polyglot相关的论文

0. 引入 Polyglot文件指的是混合类型文件&#xff0c;关于混合类型文件的基础&#xff0c;请参考文末给出的第一个链接&#xff08;参考1&#xff09;。 1. Toward the Detection of Polyglot Files 1.1 主题 这篇2022年的论文&#xff0c;提出了Polyglot文件的检测方法。虽…

C++核心编程:文件操作 笔记

5.文件操作 程序运行时产生的数据都属于临时数据&#xff0c;程序一旦允许结束都会被释放。通过文件可以将数据持久化 C中对文件操作需要包含头文件<fstream> 文件类型分为两种&#xff1a; 文本文件 - 文件以文本的ASCII码形式存储在计算机中二进制文件 - 文件以文本…

openssl3.2 - .pod文件的查看方法

文章目录 .pod文件的查看方法概述笔记初步的解决方法备注 - pod2html.bat的详细用法好像Perl就自带这个BATEND .pod文件的查看方法 概述 看到openssl源码目录下有很多.pod文件, 软件发布的帮助内容都在里面. 当make install后, 大部分的.pod都会转成html文件, 但是有一部分…

【Java程序设计】【C00215】基于SSM的勤工助学管理系统(论文+PPT)

基于SSM的勤工助学管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这个一个基于SSM的勤工助学管理系统&#xff0c;本系统共分为三种权限&#xff1a;管理员、教师和学生 管理员&#xff1a;首页、个人中心、教师管理、学生管理…

逆置字符串

将字符串逆序,比如输入abcd,返回dcba void reverse(char*left,char *right) { while (right>left) { char temp *left; *left *right; *right temp; right--; left; } } int main() { char arr[100] { 0 };//定义…

gdp调试—Linux

目录 介绍 使用 介绍 代码分为debug模式和release模式 如果一份代码要被调试&#xff0c;这份代码必须是debug Linux下编译代码默认是是release模式 如果你想代码是debug模式 必须加上 - g 小提&#xff1a; vim默认&#xff1a;命令模式 gcc默认&#xff1a;releas…

操作系统--进程、线程基础知识

一、进程 我们编写的代码只是一个存储在硬盘的静态文件&#xff0c;通过编译后就会生成二进制可执行文件&#xff0c;当我们运行这个可执行文件后&#xff0c;它会被装载到内存中&#xff0c;接着 CPU 会执行程序中的每一条指令&#xff0c;那么这个运行中的程序&#xff0c;就…

ModelArts加速识别,助力新零售电商业务功能的实现

前言 如果说为客户提供最好的商品是产品眼中零售的本质&#xff0c;那么用户的思维是什么呢&#xff1f; 在用户眼中&#xff0c;极致的服务体验与优质的商品同等重要。 企业想要满足上面两项服务&#xff0c;关键在于提升效率&#xff0c;也就是需要有更高效率的零售&#…

C++ //练习 3.8 分别用while循环和传统的for循环重写第一题的程序,你觉得哪种形式更好呢?为什么?

C Primer&#xff08;第5版&#xff09; 练习 3.8 练习 3.8 分别用while循环和传统的for循环重写第一题的程序&#xff0c;你觉得哪种形式更好呢&#xff1f;为什么? 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /********…

【三】【C++】类与对象(二)

类的六个默认成员函数 在C中&#xff0c;有六个默认成员函数&#xff0c;它们是编译器在需要的情况下自动生成的成员函数&#xff0c;如果你不显式地定义它们&#xff0c;编译器会自动提供默认实现。这些默认成员函数包括&#xff1a; 默认构造函数 (Default Constructor)&…

C++ 数论相关题目 博弈论:拆分-Nim游戏

给定 n 堆石子&#xff0c;两位玩家轮流操作&#xff0c;每次操作可以取走其中的一堆石子&#xff0c;然后放入两堆规模更小的石子&#xff08;新堆规模可以为 0 &#xff0c;且两个新堆的石子总数可以大于取走的那堆石子数&#xff09;&#xff0c;最后无法进行操作的人视为失…

PMP中的数据收集工具:打开项目成功的钥匙

在项目管理中&#xff0c;数据收集是关键的一环。准确、及时的数据能够为项目决策提供可靠的依据&#xff0c;帮助项目经理更好地监控项目进展、识别潜在风险&#xff0c;并制定有效的应对措施。本文将深入探讨PMP&#xff08;项目管理专业&#xff09;中常用的数据收集工具&am…

二层环路和三层环路

环路的原因&#xff1a;二层环路是由于物理拓扑出现环路&#xff0c;如3台交换机3角形连接。 三层环路一般物理拓扑有环路&#xff0c;并且设备之间路由表形成互指。(物理拓扑不成环&#xff0c;2台设备使用静态路由互指也可能成环&#xff0c;这种特殊情况除外)。 二层设备和三…

力扣题目训练(6)

2024年1月30日力扣题目训练 2024年1月30日力扣题目训练367. 有效的完全平方数374. 猜数字大小383. 赎金信99. 恢复二叉搜索树105. 从前序与中序遍历序列构造二叉树51. N 皇后 2024年1月30日力扣题目训练 2024年1月30日第六天编程训练&#xff0c;今天主要是进行一些题训练&…