首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在ThreadPoolExecutor中实现submit方法吞噬异常,但执行-not

在ThreadPoolExecutor中,可以通过自定义FutureTask来实现submit方法吞噬异常,但执行不阻塞的效果。

首先,需要了解ThreadPoolExecutor的submit方法返回的是一个Future对象,用于表示异步任务的执行结果。默认情况下,如果异步任务抛出异常,调用Future对象的get方法会将异常重新抛出,导致阻塞。

为了实现submit方法吞噬异常,可以自定义一个继承自FutureTask的任务类,并重写其done方法。在done方法中,可以通过调用get方法获取任务执行过程中抛出的异常,并进行处理,避免异常被重新抛出。

以下是一个示例代码:

代码语言:txt
复制
import java.util.concurrent.*;

public class ExceptionSwallowingTask<V> extends FutureTask<V> {
    public ExceptionSwallowingTask(Callable<V> callable) {
        super(callable);
    }

    @Override
    protected void done() {
        try {
            get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            // 异常处理逻辑,可以根据具体需求进行处理
            System.err.println("任务执行过程中发生异常:" + e.getCause());
        }
    }
}

public class Main {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                10, 10, 0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>()
        );

        Callable<Integer> task = () -> {
            // 模拟任务执行过程中抛出异常
            throw new RuntimeException("任务执行异常");
        };

        // 使用自定义的任务类
        Future<Integer> future = executor.submit(new ExceptionSwallowingTask<>(task));

        try {
            // 获取任务执行结果,不会抛出异常
            Integer result = future.get();
            System.out.println("任务执行结果:" + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        executor.shutdown();
    }
}

在上述代码中,自定义的ExceptionSwallowingTask类继承自FutureTask,并重写了done方法。在done方法中,通过调用get方法获取任务执行过程中的异常,并进行处理。在Main类中,使用ThreadPoolExecutor提交任务时,使用自定义的ExceptionSwallowingTask类来包装任务,从而实现了submit方法吞噬异常,但执行不阻塞的效果。

需要注意的是,通过这种方式吞噬异常可能会导致任务执行结果不可靠,因为异常被吞噬后无法及时发现。因此,在实际应用中,需要根据具体需求和场景来决定是否使用这种方式。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

如何在JavaScript中实现某个方法执行超时后则继续执行其它方法?

var executed = false; // 方法B是否执行的标志位 var x = 0; // 方法A中用来累加计数,使方法A执行超时 var expiredTime...() // 方法A的耗时内容执行开始 x = x + 1; document.counter.displayBox.value = x; for(i = 0;i < 80000;i++)...{ window.status = "i=" + i; } // 方法A的耗时内容执行结束 // 当方法A的耗时内容没有超过expiredTime的时间执行完成的话,就直接开始执行方法...B methodB(); // 设置方法B执行完成的标志位 executed = true; } // 方法B function methodB() { if(executed...methodA(); 异想天开,想用 setTimeout 来做个 workaround ,但是 setTimeout / setInterval 方法是在它所在的方法执行完之后才开始计时的

1.9K20
  • 【Python基础编程】高效并发编程及协程、线程、进程的交叉应用

    协程与传统的多线程或多进程并发模型不同,它通过事件循环实现任务的调度,在单线程内并发执行多个任务,适用于 I/O 密集型任务,如网络请求、文件操作等。...task1() 的执行不会阻塞主任务的执行。 (五)协程中的异常处理 在协程中同样可以使用 try/except 进行异常处理,这样可以确保即使某个协程抛出异常,程序依然可以继续执行。...print(f"Error caught: {e}") async def main(): await faulty_task() asyncio.run(main()) 该示例展示了如何在协程中捕获并处理异常...asyncio.gather() 和 asyncio.create_task() 实现并发任务。 异常处理、超时控制、同步函数的异步化都可以在协程中灵活应用。...协程通过 async 和 await 关键字实现异步非阻塞的 I/O 操作,适合处理 I/O 密集型任务,如网络请求、文件读写等。

    13010

    线程池实现原理

    返回结果:execute: execute方法没有返回结果,因为它只用于提交没有返回值的任务,所以无法获得任务的执行结果。submit: submit方法可以获得任务执行的结果。...异常处理:execute: execute方法不会抛出任务执行时的异常,因为没有返回结果,所以任务执行的异常只能由任务本身处理。...submit: submit方法可以通过Future对象来处理任务执行时的异常。...调用Future对象的get()方法获取任务的执行结果时,如果任务抛出异常,get()方法会将异常封装在ExecutionException中并抛出。...总结:如果你只关心任务的执行,不需要获取返回结果,可以使用execute方法。如果你需要获取任务的执行结果或处理任务执行的异常,可以使用submit方法,并将任务封装为Callable类型。

    7410

    新手也能看懂的线程池学习总结

    如果执行 ExecutorService.submit(…),ExecutorService 将返回一个实现Future接口的对象(我们刚刚也提到过了执行 execute()方法和 submit()方法的区别...() vs submit() execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否; submit()方法用于提交需要返回值的任务。...关于如何在Spring Boot 中 实现定时任务,可以查看这篇文章《5分钟搞懂如何在Spring Boot中Schedule Tasks》。...ScheduledThreadExecutor 不仅捕获运行时异常,还允许您在需要时处理它们(通过重写 afterExecute 方法ThreadPoolExecutor)。...抛出异常的任务将被取消,但其他任务将继续运行。 综上,在 JDK1.5 之后,你没有理由再使用 Timer 进行任务调度了。

    76110

    新手也能看懂的线程池学习总结

    如果执行 ExecutorService.submit(…),ExecutorService 将返回一个实现Future接口的对象(我们刚刚也提到过了执行 execute()方法和 submit()方法的区别...() vs submit() execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否; submit()方法用于提交需要返回值的任务。...关于如何在Spring Boot 中 实现定时任务,可以查看这篇文章《5分钟搞懂如何在Spring Boot中Schedule Tasks》。...ScheduledThreadExecutor 不仅捕获运行时异常,还允许您在需要时处理它们(通过重写 afterExecute 方法ThreadPoolExecutor)。...抛出异常的任务将被取消,但其他任务将继续运行。 综上,在 JDK1.5 之后,你没有理由再使用 Timer 进行任务调度了。

    55030

    新手也能看懂的线程池学习总结

    如果执行 ExecutorService.submit(…),ExecutorService 将返回一个实现Future接口的对象(我们刚刚也提到过了执行 execute()方法和 submit()方法的区别...() vs submit() execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否; submit()方法用于提交需要返回值的任务。...关于如何在Spring Boot 中 实现定时任务,可以查看这篇文章《5分钟搞懂如何在Spring Boot中Schedule Tasks》。...ScheduledThreadExecutor 不仅捕获运行时异常,还允许您在需要时处理它们(通过重写 afterExecute 方法ThreadPoolExecutor)。...抛出异常的任务将被取消,但其他任务将继续运行。 综上,在 JDK1.5 之后,你没有理由再使用 Timer 进行任务调度了。

    40420

    如何处理JDK线程池内线程执行异常?讲得这么通俗,别还搞不懂

    如何处理运行任务时抛出的异常 这个问题我们以 execute() 为例, 先看下源码中是如何处理的 如果看过前面两篇线程池文章的小伙伴对第一个任务执行流程是比较清晰的 execute() -> addWorker...而线程组中牵扯到批量管理线程,如批量停止或挂起等概念, 这里不过多分析 获取到具体执行策略后, 我们查看下 ThreadGroup#uncaughtException 是如何处理的 public void...catch 住, 所以不会将异常信息默认打印 那如何能够知道 submit() 是否抛出了异常?...submit() 返回值是 Future 接口, 默认实现是 FutureTask, 内部有一个 get() 方法, 既可以获取返回值, 同时也可以抛出对应异常 public V get() throws...ExecutionException((Throwable) x); } 在任务发生异常时, 会将异常进行报错, 通过 get() 方法可以返回任务执行异常 4.

    44420

    深入浅出线程池创建和使用

    ()//线程拒绝策略,也可以不用传参);五:线程池ThreadPoolExecutor中execute和submit方法对比(1)定义方法的类不同 submit是在ExecutorService接口中定义的...,而execute方法是在Executor类中定义的,ThreadPoolExecutor实现。...2)返回值类型不同execute方法返回值为空,submit方法会以Future的形式返回线程的执行结果。...(3)对异常的处理方式不同如果执行的任务中产生了异常,execute()方法会直接打印产生的异常的堆栈,由于该异常是在子线程中产生,主线程中包围在execute方法周围的try-catch语句不能捕获异常...而submit提交的子线程如果产生了异常,当调用submit方法返回的Future实例的get方法时,可以在主线程try-catch捕获异常。

    27210

    Java异步编程——深入源码分析FutureTask

    通过创建一个ThreadPoolExecutor,往里面丢任务就可以实现多线程异步执行了。 但之前的任务主要倾向于线程池,并没有讲到异步编程方面的内容。...Demo中为了方便,直接调用Exectors的方法生成一个临时的线程池,日常不建议使用。 我们从这个ExecutorService.submit()方法入手,看看整体实现。 ?...看回ExecutorService.submit()的实现,代码在实现类AbstractExecutorService中。 ? 除了它接口的实现,还提供了两种变形。...原来接口只接收Callable参数,实现类中还新增了接收Runnable参数的。 如果看过之前写的《你真的懂ThreadPoolExecutor线程池技术吗?...submit()的原理是利用Callable创建一个FutureTask对象,然后执行对象的run()方法,把结果保存在outcome中。

    60830

    Java高频面试之并发篇

    在并行处理中,任务被划分为多个子任务,并且这些子任务可以同时执行,每个子任务分配给不同的处理单元(如多核处理器或分布式系统中的多个计算节点)。...在并发处理中,系统可能只有一个处理单元,但任务通过时间片轮转或其他调度算法进行切换,以实现多个任务的看似同时执行。并发可以提高系统的响应能力和资源利用率,特别是在涉及输入/输出等等待时间的情况下。...线程是进程中的一个执行单元,多个线程可以共享进程的内存空间和系统资源。 线程切换开销相对小,但需要进行同步操作;进程是具有独立地址空间和资源的执行实例,切换开销大,但数据隔离性好。 守护线程是什么?...执行 execute() 方法和 submit() 方法的区别是什么呢? 返回值:execute()没有返回值,submit() 有返回值 异常处理:execute() 方法没有提供任何异常处理机制。...如果提交的任务在执行过程中抛出异常,它将由内部的 UncaughtExceptionHandler 处理。而 submit()在获取结果的时候可以捕获到异常,然后自己处理。

    11411

    详解 ThreadPoolExecutor 的参数含义及源码执行流程?

    但如果要说线程池的话一定离不开 ThreadPoolExecutor ,在阿里巴巴的《Java 开发手册》中是这样规定线程池的: 线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor...ThreadPoolExecutor 能不能实现扩展?如何实现扩展?...知识扩展 execute() VS submit() execute() 和 submit() 都是用来执行线程池任务的,它们最主要的区别是,submit() 方法可以接收线程池执行的返回值,而 execute...Success 从以上结果可以看出 submit() 方法可以配合 Futrue 来接收线程执行的返回值。...ThreadPoolExecutor 扩展 ThreadPoolExecutor 的扩展主要是通过重写它的 beforeExecute() 和 afterExecute() 方法实现的,我们可以在扩展方法中添加日志或者实现数据统计

    23110

    线程池原理(1)

    Runnable 接口和 Callable 接口的区别 Runnable自 Java 1.0 以来一直存在,但Callable仅在 Java 1.5 中引入,目的就是为了来处理Runnable不支持的用例...submit()方法的区别 execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否; submit()方法用于提交需要返回值的任务。...SingleThreadExecutor:方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。...CachedThreadPool:该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。...ThreadPoolExecutor.CallerRunsPolicy:调用执行自己的线程运行任务,也就是直接在调用execute方法的线程中运行(run)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务

    44310

    对线面试官-线程池(二)

    面试官:那么execute()和submit()在异常处理方面有什么区别吗? 派大星:execute()会直接抛出任务执行时的异常,可以使用try catch来捕获,和普通线程的处理方式完全一致。...而submit()会吃掉异常,可以通过Future的get方法将任务执行时的异常重新抛出。 面试官:那么execute()和submit()的返回值有什么区别呢?...ThreadPoolExecutor()中并没有定义,但是ThreadPoolExecutor类继承了AbstractExecutorService抽象类,而该抽象类实现了ExecutorService...总结:也就是说ThreadPoolExecutor实现了execute()方法, 具体来说,AbstractExecutorService类中submit方法被重载了三次,分别接受Runnable、Callable...而ThreadPoolExecutor类中只实现了接受Runnable类型参数的execute方法。另外,submit方法会返回一个Future对象,而execute方法没有返回值。

    13210

    线程池-从零到一了解并掌握线程池

    submit会吃掉异常,可以通过Future的get方法将任务执行时的异常重新抛出。...ThreadPoolExecutor()中并没有定义,但是ThreadPoolExecutor类继承了AbstractExecutorService抽象类,而该抽象类实现了ExecutorService...总结:也就是说ThreadPoolExecutor实现了execute()方法, submit()方法时ExecutorService接口中定义的,具体的实现是由AbstractExecutorService...捕获线程池中的异常 有两种种方法可以捕获线程池中的异常。 一种方法是通过手动使用try-catch块来捕获异常并打印出来,但这样的写法比较繁琐和不够优雅。...当线程抛出异常时,JVM最终会回调这个方法来进行最后的异常处理,而且该异常会被ThreadGroup类中的uncaughtException方法处理。

    20810
    领券