线程池中某个线程执行有异常,该如何处理?
Posted master-dragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池中某个线程执行有异常,该如何处理?相关的知识,希望对你有一定的参考价值。
目录
1. 线程池抛出异常代码
class Task implements Runnable
@Override
public void run()
System.out.println("task start...");
int i = 1 / 0;
System.out.println("task end...");
class MyThreadFactoryTest implements ThreadFactory
private final AtomicInteger count = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r)
int c = count.incrementAndGet();
Thread t = new Thread(r);
t.setName("MyThreadFactory.thread." + c);
return t;
public class Tmp
public static void main(String[] args)
ExecutorService executorService = Executors.newFixedThreadPool(1, new MyThreadFactoryTest());
executorService.submit(new Task());
executorService.execute(new Task());
executorService.shutdown();
输出:
executorService.submit
没有打印出异常
使用future可以打印,如下
submit 底层仍然是执行execute,只不过封装了一层future,所以需要future.get()才能进行异常捕获和处理
2. 如何获取和处理异常
方法1: 线程自身打印异常
方法2: 使用Thread.setUncaughtExceptionHandler设置线程自己的异常处理
如果要求每个任务都自主加上try ... catch...
显然不太合适,无法要求每个人,就自己做改变吧…
class Task implements Runnable
@Override
public void run()
System.out.println("task start...");
int i = 1 / 0;
System.out.println("task end...");
class MyThreadFactoryTest implements ThreadFactory
private final AtomicInteger count = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r)
int c = count.incrementAndGet();
Thread t = new Thread(r);
t.setName("MyThreadFactory.thread." + c);
t.setUncaughtExceptionHandler((thread, e)->
System.out.println("线程工厂设置ExceptionHandler:"+thread.getName() + ":" + e);
);
return t;
public class Tmp
public static void main(String[] args)
ExecutorService executorService = Executors.newFixedThreadPool(1, new MyThreadFactoryTest());
// 仍然无打印
executorService.submit(new Task());
// 被线程工厂设置ExceptionHandler捕获到异常
executorService.execute(new Task());
executorService.shutdown();
附:java.util.concurrent.ThreadPoolExecutor#runWorker
通过阅读源码,execute一个任务,如果能成功执行,会被封装成一个worker,然后执行runWorker方法
final void runWorker(Worker w)
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try
while (task != null || (task = getTask()) != null)
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try
beforeExecute(wt, task);
Throwable thrown = null;
try
//线程执行
task.run();
// 各种异常捕获
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);
方法3: 重写线程池的afterExecute方法
当然Thread.setUncaughtExceptionHandler仍然有效
class Task implements Runnable
@Override
public void run()
System.out.println("task start...");
int i = 1 / 0;
System.out.println("task end...");
class MyThreadFactoryTest implements ThreadFactory
private final AtomicInteger count = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r)
int c = count.incrementAndGet();
Thread t = new Thread(r);
t.setName("MyThreadFactory.thread." + c);
return t;
public class Tmp
public static void main(String[] args)
ExecutorService executorService = new ThreadPoolExecutor(2, 10,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
new MyThreadFactoryTest())
@Override
protected void afterExecute(Runnable r, Throwable t)
System.out.println("afterExecute:" + Thread.currentThread().getName() + ":" + t);
;
// 仍然无打印
executorService.submit(new Task());
// 被线程工厂设置ExceptionHandler捕获到异常
executorService.execute(new Task());
executorService.shutdown();
submit的任务afterExecute单独内部判断处理
以上是关于线程池中某个线程执行有异常,该如何处理?的主要内容,如果未能解决你的问题,请参考以下文章
京东二面:线程池中的线程抛出了异常,该如何处理?大部分人都会答错!