经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
Java面试题:线程池内“闹情绪”的线程,怎么办?
来源:cnblogs  作者:猫鱼吐泡泡  时间:2024/5/13 8:54:21  对本文有异议

在Java中,线程池中工作线程出现异常的时候,默认会把异常往外抛,同时这个工作线程会因为异常而销毁,我们需要自己去处理对应的异常,异常处理的方法有几种:

  • 在传递的任务中去处理异常,对于每个提交到线程池中的执行的任务,可以提前通过异常进行捕获,这样即便出现了异常,也不会影响线程池中的工作线程

  • 使用Future来捕获异常结果,在线程池中提供了一个submit(Callable<T>)方法,这个方法会返回一个Future,可以通过调用Future.get()方法,来获取任务的执行结果,如果任务执行过程中出现了异常,也会抛出一个ExecutionException,其中就包含了任务执行过程中出现的异常

  • 我们还可以自定义一个ThreadFactory,设置一个UncaughtExceptionHandler,我们可以通过实现ThreadFactory的接口来自定义创建线程的方式,然后为每个新创建的线程设置一个UncaughtExceptionHandler,这个处理器会在线程由于未捕获异常而即将终止的时候被调用

下面是三段代码示例:

捕获线程执行异常

  1. ExecutorService executorService = Executors.newFixedThreadPool(5);
  2.  
  3. executorService.execute(() -> {
  4. try {
  5. // 执行任务
  6. } catch (Exception e) {
  7. // 记录日志
  8. logger.error("An exception occurred: ", e);
  9. }
  10. });

在执行任务的过程中,如果出现异常,就会被try-catch语句捕获,并将异常信息记录到日志中。

 

使用Future来捕获异常结果

  1. ExecutorService executorService = Executors.newFixedThreadPool(5);
  2.  
  3. List<Future<?>> futures = new ArrayList<>();
  4.  
  5. // 提交任务到线程池
  6. for (int i = 0; i < 10; i++) {
  7. Future<?> future = executorService.submit(() -> {
  8. // 执行任务
  9. });
  10. futures.add(future);
  11. }
  12.  
  13. // 获取任务结果
  14. for (Future<?> future : futures) {
  15. try {
  16. future.get();
  17. } catch (InterruptedException | ExecutionException e) {
  18. // 处理异常
  19. logger.error("An exception occurred: ", e);
  20. }
  21. }

在这个例子中,我们将多个任务提交到线程池,并将每个任务的Future对象保存在futures列表中。接着,我们遍历futures列表,并调用每个Future对象的get()方法来获取任务的执行结果。如果任务执行过程中出现了异常,则会抛出ExecutionException异常,我们在catch块中捕获该异常并进行相应的处理。

 

实现UncaughtExceptionHandler接口

  1. public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler {
  2. @Override
  3. public void uncaughtException(Thread t, Throwable e) {
  4. // 记录日志或者进行其它处理
  5. logger.error("Thread " + t.getName() + " encountered an exception: ", e);
  6. }
  7. }
  8.  
  9. ExecutorService executorService = Executors.newFixedThreadPool(5);
  10.  
  11. // 设置UncaughtExceptionHandler
  12. ((ThreadPoolExecutor) executorService).setThreadFactory(r -> {
  13. Thread thread = new Thread(r);
  14. thread.setUncaughtExceptionHandler(new CustomExceptionHandler());
  15. return thread;
  16. });
  17.  
  18. executorService.execute(() -> {
  19. // 执行任务
  20. });

这种方式需要自定义一个实现了UncaughtExceptionHandler接口的异常处理器,当线程出现异常时,异常处理器会被调用,我们可以在其中记录日志或者进行其它处理。接着,我们需要将异常处理器设置到线程池的线程工厂中。当线程池内的线程出现异常时,异常处理器就会被调用,我们可以在其中处理异常。

  

原文链接:https://www.cnblogs.com/marsitman/p/18187655

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号