解析Java线程池的异常处理机制

简介: 该内容是一个关于Java线程和线程池异常处理的总结。提到的关键点包括:1. 引用了滑动验证页面和相关文章资源。2. 区分了`execute`与`submit`在处理线程异常时的区别,`submit`可能会捕获并隐藏异常,而`execute`会直接抛出。3. 提供了处理线程和线程池异常的建议,如使用try/catch直接捕获,或者自定义线程工厂和未捕获异常处理器。4. 示例代码展示了如何通过设置`UncaughtExceptionHandler`来监控和处理线程中的异常。请注意,由于字符限制,这里只提供了简要摘要,详细解释和代码示例请参考原文。

 

感谢:1、滑动验证页面

2、线程的异常捕获与线程池的异常捕获 execute与submit区别:线程的异常捕获与线程池的异常捕获 execute与submit区别_threadutil.execute-CSDN博客

原文:https://www.cnblogs.com/wscit/p/6100476.html

3、线程吞掉异常信息 - 简书

submit的方式会吃掉异常,execute的方式会直接抛出

之后定义的时候要这样定义

对于线程池、包括线程的异常处理推荐一下方式:

  1. 直接try/catch
@Test
    public void catchThreadPoolTest() {
        ExecutorService threadPool = Executors.newFixedThreadPool(1);
        try {
            Runnable runnable = () -> {
                System.out.println("-----------submit---------------");
                Object obj = null;
                System.out.println(obj.toString());
            };
            threadPool.submit(runnable).get();
        } catch (Exception e) {
            System.out.println("---------submit  Exception---------");
            e.printStackTrace();
        }
        System.out.println("-----------华丽的分割线---------------");
        threadPool.execute(() -> {
            try {
                Object obj = null;
                System.out.println(obj.toString());
            } catch (Exception e) {
                System.out.println("---------execute  Exception-----------");
                e.printStackTrace();
            }
        });
    }

image.gif

2、线程直接重写整个方法:

第一段代码仅限于execute方法,因为submit的异常在线程池定义那块捕获不到,只有get的时候才会抛出,并且影响主线程的进行


@Test
    public void threadPoolTest() {
        ExecutorService threadPool = Executors.newFixedThreadPool(1, r -> {
            Thread t = new Thread(r);
            t.setUncaughtExceptionHandler(
                    (t1, e) -> System.out.println(t1 + " throws exception: " + e));
            return t;
        });
        threadPool.execute(() -> {
            System.out.println("-----------execute---------------");
            Object obj = null;
            System.out.println(obj.toString());
            System.out.println("-----------obj.toString---------------");
        });
        System.out.println("-----------afterExecue---------------");
    }
image.gif


@Test
    public void catchedExecutor() {
        ExecutorService executorService = Executors.newCachedThreadPool(new MyThreadFactory());
        executorService.execute(new Task());
        executorService.shutdownNow();
        System.out.println("-----------start---------------");
    }
public class MyThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
        System.out.println("Thread[" + t.getName() + "] created.");
        return t;
    }
}
public class Task implements Runnable {
    public void run() {
        System.out.println("执行任务");
        int num  = Integer.parseInt("TT");
    }
}
public class RewriteUncatchtExceptionHandler implements Thread.UncaughtExceptionHandler {
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("我捕获到了线程池的异常");
    }
}
image.gif


@Test
    public void rewriteUncaughtException() {
        Task task = new Task();
        Thread thread = new Thread(task);
        thread.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
        thread.start();
        System.out.println("-----------start---------------");
    }
public class RewriteUncatchtExceptionHandler implements Thread.UncaughtExceptionHandler{
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("我捕获到了线程池的异常");
    }
}
public class Task implements Runnable {
    public void run() {
        System.out.println("执行任务");
        int num  = Integer.parseInt("TT");
    }
}
image.gif


@Test
    public void rewriteAfterExecute() {
        ExecutorService threadPool2 = new MyThreadPoolExecutor(1, 1, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
        threadPool2.execute(() -> {
            System.out.println("-----------execute---------------");
            Object obj = null;
            System.out.println(obj.toString());
        });
        System.out.println("-----------afterExecue---------------");
    }
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
    protected void afterExecute(Runnable r, Throwable t) {
        if(t!=null){
            System.out.println("MyThreadPoolExecutor     "+t);
        }
    }
}
image.gif

Thread t = new Thread();
       t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
 
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
        });
        //如果是线程池的模式:
        ExecutorService threadPool = Executors.newFixedThreadPool(1, r -> {
 Thread t = new Thread(r);
 t.setUncaughtExceptionHandler(
  (t1, e) -> LOGGER.error(t1 + " throws exception: " + e));
 return t;
        });
  1. image.gif
目录
相关文章
|
1天前
|
缓存 算法 Java
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
|
1天前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
|
1天前
|
缓存 安全 Java
7张图带你轻松理解Java 线程安全,java缓存机制面试
7张图带你轻松理解Java 线程安全,java缓存机制面试
|
1天前
|
存储 缓存 安全
第二章 HTTP请求方法、状态码详解与缓存机制解析
第二章 HTTP请求方法、状态码详解与缓存机制解析
|
2天前
|
存储 安全 算法
【常见集合】Java 常见集合重点解析
【常见集合】Java 常见集合重点解析
6 0
|
2天前
|
Java 开发工具 Maven
java解析apk获取应用信息
请注意,你需要替换"path/to/your/apkfile.apk"为你的APK文件的实际路径。
10 0
|
2天前
|
消息中间件 安全 前端开发
字节面试:说说Java中的锁机制?
Java 中的锁(Locking)机制主要是为了解决多线程环境下,对共享资源并发访问时的同步和互斥控制,以确保共享资源的安全访问。 锁的作用主要体现在以下几个方面: 1. **互斥访问**:确保在任何时刻,只有一个线程能够访问特定的资源或执行特定的代码段。这防止了多个线程同时修改同一资源导致的数据不一致问题。 2. **内存可见性**:通过锁的获取和释放,可以确保在锁保护的代码块中对共享变量的修改对其他线程可见。这是因为 Java 内存模型(JMM)规定,对锁的释放会把修改过的共享变量从线程的工作内存刷新到主内存中,而获取锁时会从主内存中读取最新的共享变量值。 3. **保证原子性**:锁
17 1
|
2天前
|
安全 Java 数据安全/隐私保护
Java一分钟之-Java反射机制:动态操作类与对象
【5月更文挑战第12天】本文介绍了Java反射机制的基本用法,包括获取Class对象、创建对象、访问字段和调用方法。同时,讨论了常见的问题和易错点,如忽略访问权限检查、未捕获异常以及性能损耗,并提供了相应的避免策略。理解反射的工作原理和合理使用有助于提升代码灵活性,但需注意其带来的安全风险和性能影响。
23 4
|
2天前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的深度解析
【5月更文挑战第12天】本文将深入探讨Java 8中的两个重要新特性:Lambda表达式和Stream API。我们将从基本概念入手,逐步深入到实际应用场景,帮助读者更好地理解和掌握这两个新特性,提高Java编程效率。
41 2
|
1天前
HuggingFace Tranformers 源码解析(4)
HuggingFace Tranformers 源码解析
5 0

推荐镜像

更多