本文主要是介绍Java捕获ThreadPoolExecutor内部线程异常的四种方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感...
方案 1
使用 execute
+ try-catch
记录异常
import Java.util.concurrent.*; public class ThreadPoolExceptionDemo { public static vwww.chinasem.cnoid main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 4, 10, TimeUnit.SECONDS, new LinkedblockingQueue<>(), new ThreadFactory() { private int count = 1; @Override public Thread newThread(Runnable r) { return new Thread(r, "custom-thread-" + count++); } }); executor.execute(() -> { try { System.out.println(Thread.currentThread().getName() + " 正在执行任务"); throw new RuntimeException("任务异常"); } catch (Exception e) { System.err.println("线程 " + Thread.currentThread().getName() + " 捕获异常: " + e.getMessage()); e.printStackTrace(); } }); executor.shutdown(); } }
方案 2
使用 submit + Future
submit()
方法返回 Future
,可以通过 get()
方法捕获异常:
public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(2); Future<?> future = executor.submiwww.chinasem.cnt(() -> { System.out.println(Thread.currentThread().getName() + " 正在执行任务"); throw new RuntimeException("任务异常"); }); try { future.get(); // get() 会抛出 ExecutionException } catch (InterruptedException | ExecutionException e) { System.err.println("线程 " + Thread.currentThread().getName() + " 捕获异常: " + e.getCause().getMessage()); e.printStackTrace(); } executor.shutdown(); }
注意
- get() 方法会阻塞主线程直到任务完成。
- ExecutionException 的 getCause() 方法可以获取原始异常。
方案 3
自定义 UncaughtExceptionHandler
可以为线程设置 UncaughtExceptionHandler,当 Runnable 没有捕获异常时,ThreadPoolExecutor 也不会吞掉异常:
public class ThreadPoolWithExceptionHandler {
public static void main(String[] args) {
ThreadFactory threadFactory = r -> {
Thread t = new Thread(r);
t.setUncaughtExceptionHandler((thread, throwable) -> {
System.err.println("线程 " + thread.getName() + " 发生异常: " + throwable.getMessage());
throwable.printStackTrace();
});
returnChina编程 t;
};
ExecutorService executor = new ThreadPoolExecutor(
2, 4, 10, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
threadFactory
);
executor.execute(() -> {
System.out.println(Thread.currentThread().getName() + " 正在执行任务");
throw new RuntimeException("任务异常");
});
executor.shutdown();
}
}
方案 4
重写 afterExecute 方法
如果你要在 ThreadPoolExecutor
内部直接处理异常,可以继承 ThreadPoolExecutor
并重写 afterExecute()
:
class CustomThreadPoolExecutor extends ThreadPoolExecutor { public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (t == null && r instanceof Future<?>) { try { ((Future<?>) r).get(); // 获取任务结果,捕获异常 } catch (InterruptedException | ExecutionException e) { t = e.getCause(); } } if (t != null) { System.err.println("线程 " + Thread.currentThread().getName() + " 发生异常: " + t.getMessage()); t.printStackTrace(); } } } public class ThreadPoolAfterExecuteDemo { public static void main(String[] args) { ThreadPoolExecutor executor = new CustomThreadPoolExecutor(2, 4, 10, TimeUnit.SECOChina编程NDS, new LinkedBlockingQueue<>()); executor.submit(() -> { System.out.println(Thread.currentThread().getName() + " 正在执行任务"); throw new RuntimeException("任务异常"); }); executor.shutdown(); } }
结论
方案 | 适用场景 | 缺点 |
---|---|---|
try-catch 手动处理 | 适用于 execute() | 代码侵入性强,所有任务都要加 try-catch |
Future.get() 捕获异常 | 适用于 submit() | get() 会阻塞主线程 |
UncaughtExceptionHandler | 适用于 exe编程China编程cute() | 不能捕获 submit() 提交的异常 |
afterExecute() | 适用于 execute() 和 submit() | 需要继承 ThreadPoolExecutor |
推荐:
- 任务内部
try-catch
适用于execute()
Future.get()
适用于submit()
- 统一异常处理建议使用
afterExecute()
或UncaughtExceptionHandler
到此这篇关于Java捕获ThreadPoolExecutor内部线程异常的四种方法的文章就介绍到这了,更多相关Java ThreadPoolExecutor异常内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于Java捕获ThreadPoolExecutor内部线程异常的四种方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!