Java面试题:线程池内“闹情绪”的线程,怎么办?
在Java中,线程池中工作线程出现异常的时候,默认会把异常往外抛,同时这个工作线程会因为异常而销毁,我们需要自己去处理对应的异常,异常处理的方法有几种:
在传递的任务中去处理异常,对于每个提交到线程池中的执行的任务,可以提前通过异常进行捕获,这样即便出现了异常,也不会影响线程池中的工作线程
使用Future来捕获异常结果,在线程池中提供了一个submit(Callable<T>)方法,这个方法会返回一个Future,可以通过调用Future.get()方法,来获取任务的执行结果,如果任务执行过程中出现了异常,也会抛出一个ExecutionException,其中就包含了任务执行过程中出现的异常
我们还可以自定义一个ThreadFactory,设置一个UncaughtExceptionHandler,我们可以通过实现ThreadFactory的接口来自定义创建线程的方式,然后为每个新创建的线程设置一个UncaughtExceptionHandler,这个处理器会在线程由于未捕获异常而即将终止的时候被调用
下面是三段代码示例:
捕获线程执行异常
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.execute(() -> {
try {
// 执行任务
} catch (Exception e) {
// 记录日志
logger.error("An exception occurred: ", e);
}
});
在执行任务的过程中,如果出现异常,就会被try-catch语句捕获,并将异常信息记录到日志中。
使用Future来捕获异常结果
ExecutorService executorService = Executors.newFixedThreadPool(5); List<Future<?>> futures = new ArrayList<>(); // 提交任务到线程池
for (int i = 0; i < 10; i++) {
Future<?> future = executorService.submit(() -> {
// 执行任务
});
futures.add(future);
} // 获取任务结果
for (Future<?> future : futures) {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
// 处理异常
logger.error("An exception occurred: ", e);
}
}
在这个例子中,我们将多个任务提交到线程池,并将每个任务的Future对象保存在futures列表中。接着,我们遍历futures列表,并调用每个Future对象的get()方法来获取任务的执行结果。如果任务执行过程中出现了异常,则会抛出ExecutionException异常,我们在catch块中捕获该异常并进行相应的处理。
实现UncaughtExceptionHandler接口
public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
// 记录日志或者进行其它处理
logger.error("Thread " + t.getName() + " encountered an exception: ", e);
}
}
ExecutorService executorService = Executors.newFixedThreadPool(5);
// 设置UncaughtExceptionHandler
((ThreadPoolExecutor) executorService).setThreadFactory(r -> {
Thread thread = new Thread(r);
thread.setUncaughtExceptionHandler(new CustomExceptionHandler());
return thread;
});
executorService.execute(() -> {
// 执行任务
});
这种方式需要自定义一个实现了UncaughtExceptionHandler接口的异常处理器,当线程出现异常时,异常处理器会被调用,我们可以在其中记录日志或者进行其它处理。接着,我们需要将异常处理器设置到线程池的线程工厂中。当线程池内的线程出现异常时,异常处理器就会被调用,我们可以在其中处理异常。
Java面试题:线程池内“闹情绪”的线程,怎么办?的更多相关文章
- 线程池内的异步线程创建UI控件,造成UI线程卡死无响应的问题分析
winform应用在使用一段时间后,切换到其他系统或者打开word.excel文档,再切换回winform应用时,系统有时出现不响应的现象.有时在锁屏后恢复桌面及应用时也发生此问题. 经微软支持确认, ...
- 一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)
这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 21.对线程安全的理解 22.Thread和Runnable的区别 23.说说你对守护线程的理解 24.ThreadLoc ...
- Java 面试题 三 <JavaWeb应用调优线程池 JVM原理及调优>
1.Java Web应用调优线程池 不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文由浅入深,介 ...
- Java线程池中的核心线程是如何被重复利用的?
真的!讲得太清楚了!https://blog.csdn.net/MingHuang2017/article/details/79571529 真的是解惑了 本文所说的"核心线程". ...
- java多线程系类:JUC线程池:05之线程池原理(四)(转)
概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...
- java多线程系类:JUC线程池:03之线程池原理(二)(转)
概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...
- java多线程系类:JUC线程池:02之线程池原理(一)
在上一章"Java多线程系列--"JUC线程池"01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我 ...
- java多线程、线程池及Spring配置线程池详解
1.java中为什么要使用多线程使用多线程,可以把一些大任务分解成多个小任务来执行,多个小任务之间互不影像,同时进行,这样,充分利用了cpu资源.2.java中简单的实现多线程的方式 继承Thread ...
- java线程池及创建多少线程合适
java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...
- 面试官不按套路,竟然问我Java线程池是怎么统计线程空闲时间?
背景介绍: 你刚从学校毕业后,到新公司实习,试用期又被毕业,然后你又不得不出来面试,好在面试的时候碰到个美女面试官! 面试官: 小伙子,我看你简历上写的项目中用到了线程池,你知道线程池是怎样实现复用线 ...
随机推荐
- AtCoder Regular Contest 115(without F)
ARC115 A - Two Choices 题目传送门 分析 可以发现正确答案数量相同当且仅当 \(S_i\) xor \(S_j\) 所含有的 1 的数量为偶数. 再将这个简化一下,正确答案相同当 ...
- #树形dp,二次扫描换根法#洛谷 4284 [SHOI2014]概率充电器
题目 分析 充电很难做,考虑判断不充电的概率, 设\(dp[x]\)表示点\(x\)无法充电的概率,但是这样有后效性, 考虑先处理子树内的问题,那么 \(dp[x]=(1-p[x])\prod_{y\ ...
- 基于istio实现单集群地域故障转移
本文分享自华为云社区<基于istio实现单集群地域故障转移>,作者:可以交个朋友. 一 背景 随着应用程序的增长并变得更加复杂,微服务的数量也会增加,失败的可能性也会增加.微服务的故障可能 ...
- button submit你以为你阻止了默认事件?
前言 先解决掉一个误区: 很多人写button的时候,就这样写: <button><botton> 你认为就是默认的submit的时候,这时候就可能出问题了. 当然之所以你没有 ...
- redis 简单整理——HyperLogLog[十三]
前言 简单介绍一下HyperLogLog. 正文 HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而 是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数 ...
- Unable to determine application id: com.android.tools.idea.run.ApkProvisionException: No outputs for the main artifact of variant: debug
前言 遇到这种情况极大可能属于gradle 与 android studio版本不匹配的情况. 因为我是在升级android studio遇到的这个问题. 方法 一个方法是:降低android stu ...
- 重新整理.net core 计1400篇[四] (.net core 修改sdk )
前言 可能有些人还不知道什么是sdk,software development kit,中文是软件开发包的意思. 然后什么是软件开发包? 软件开发工具包是一些被软件工程师用于为特定的软件包.软件框架. ...
- IIS 出现405
前言 在一次配置服务器中,出现一个问题,那就是使用put和delete 出现405. 当时我蒙了,调试的时候好好的,部署405. 原因是put和delete是非简单请求,也就是说非安全请求了. 这时候 ...
- Webpack中Loader和Plugin的区别?编写Loader,Plugin的思路?
一.区别 前面两节我们有提到Loader与Plugin对应的概念,先来回顾下 loader 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译.压缩等,最终一起打包到指定的文件中 pl ...
- tensorflow如何切换CPU和GPU
import os if Bert_Use_GPU: os.environ['CUDA_VISIBLE_DEVICES'] = '0,1' #使用GPU0,1 else: os.environ['CU ...