当前位置: 代码网 > it编程>编程语言>Java > Java捕获ThreadPoolExecutor内部线程异常的四种方法

Java捕获ThreadPoolExecutor内部线程异常的四种方法

2025年03月13日 Java 我要评论
方案 1使用execute+try-catch记录异常import java.util.concurrent.*; public class threadpoolexceptiondemo {

方案 1

使用 execute + try-catch 记录异常

import java.util.concurrent.*;
 
public class threadpoolexceptiondemo {
    public static void 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.submit(() -> {
        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();
            });
            return 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.seconds, 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适用于 execute()不能捕获 submit() 提交的异常
afterexecute() 适用于 execute() 和 submit()需要继承 threadpoolexecutor

推荐:

  • 任务内部 try-catch 适用于 execute()
  • future.get() 适用于 submit()
  • 统一异常处理建议使用 afterexecute() 或 uncaughtexceptionhandler

到此这篇关于java捕获threadpoolexecutor内部线程异常的四种方法的文章就介绍到这了,更多相关java threadpoolexecutor异常内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com