线程池中线程抛异常

java中的线程池是一个非常重要的多线程编程工具,它可以通过预先创建一组线程并维护着队列来管理并发很高的任务。在使用线程池时,开发人员可以使用两个主要的方法submit()和execute()提交任务。

线程池中submit()和execute()方法的区别主要体现在返回值、异常处理、任务类型支持以及任务处理方式等方面。‌

  1. ‌返回值‌:

    • ‌execute()方法‌:没有返回值。它主要用于提交不需要返回结果的Runnable任务‌
    • ‌submit()方法‌:可以提交Runnable或Callable任务,并返回一个Future对象。通过Future对象,可以获取任务的执行结果、判断任务是否完成、取消任务执行以及获取任务执行中抛出的异常‌
  2. ‌异常处理‌:

    • ‌execute()方法‌:如果任务执行过程中抛出未捕获的异常,异常会被传递给线程池的UncaughtExceptionHandler,开发者需要手动在任务内部捕获异常,否则异常会丢失‌
    • ‌submit()方法‌:如果任务执行过程中抛出异常,异常会被封装在Future对象中,调用Future.get()时会抛出ExecutionException。开发者可以通过Future.get()捕获并处理异常‌.
  3. ‌任务类型支持‌:

    • ‌execute()方法‌:只能接收Runnable类型的任务,Runnable任务没有返回值‌
    • ‌submit()方法‌:既可以接收Runnable任务,也可以接收Callable任务。Callable任务可以返回结果‌。
  4. 任务处理方式‌:

    • ‌execute()方法‌:提交的任务直接在调用线程(通常是主线程)中运行,适用于不需要返回结果且希望立即执行的场景‌
    • ‌submit()方法‌:提交的任务会被添加到阻塞队列中,由线程池中的工作线程处理。提交任务的线程可以继续执行其他任务,直到任务执行完毕并返回结果‌。

 

 

用伪代码模拟一下线程池抛异常的场景:


public class ThreadPoolException {
    public static void main(String[] args) {

        //创建一个线程池
        ExecutorService executorService= Executors.newFixedThreadPool(1);

        //当线程池抛出异常后 submit无提示,其他线程继续执行
        executorService.submit(new task());

        //当线程池抛出异常后 execute抛出异常,其他线程继续执行新任务
        executorService.execute(new task());
    }
}

//任务类
class task implements  Runnable{

    @Override
    public void run() {
        System.out.println("进入了task方法!!!");
        int i=1/0;

    }
}

运行结果:

submit()想要获取异常信息就必须使用get()方法!!


//当线程池抛出异常后 submit无提示,其他线程继续执行
Future<?> submit = executorService.submit(new task());
submit.get();


2. 如何获取和处理异常


方案一:使用 try -catch

public class ThreadPoolException {
    public static void main(String[] args) {
        
        //创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(1);

        //当线程池抛出异常后 submit无提示,其他线程继续执行
        executorService.submit(new task());

        //当线程池抛出异常后 execute抛出异常,其他线程继续执行新任务
        executorService.execute(new task());
    }
}
// 任务类
class task implements Runnable {
    @Override
    public void run() {
        try {
            System.out.println("进入了task方法!!!");
            int i = 1 / 0;
        } catch (Exception e) {
            System.out.println("使用了try -catch 捕获异常" + e);
        }
    }
}

 

打印结果:

 

可以看到 submit 和 execute都清晰易懂的捕获到了异常,可以知道我们的任务出现了问题,而不是消失的无影无踪。

 

方案二:使用Thread.setDefaultUncaughtExceptionHandler方法捕获异常

 

UncaughtExceptionHandler 是Thread类一个内部类,也是一个函数式接口。

内部的uncaughtException是一个处理线程内发生的异常的方法,参数为线程对象t和异常对象e。

 方案三:重写afterExecute进行异常处理

在excute的方法里面,可以通过重写afterExecute进行异常处理,但是注意! 这个也只适用于excute提交

posted @   KLAPT  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-02-25 API接口的安全设计验证:ticket,签名,时间戳
点击右上角即可分享
微信分享提示