线程池ThreadPool 的submit()和excute()方式执行任务对任务异常的处理

线程池类的继承实现关系

Executor接口<----extend---ExecutorService接口<----implements----AbstractExecutorService抽象类(没有覆盖excute方法)<----extend---ThreadPoolExecutor

submit()

ExecutorService pool = Executors.newFixedThreadPool(30);
pool.submit(new Runnable(){})

源码示例:

public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

##submit(Runnable) 会返回一个Fture对象,该 Future 的 get 方法在成功 完成时将会返回null。内部也是调用execute(task)

excute()

 ExecutorService pool = Executors.newFixedThreadPool(30);
 pool.excute(new Runnable(){});

源码示例:

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

追溯源码,excute(Runnable) 不会返回任何对象,无法判断是否执行成功,但是其对task对象内部的异常并未进行catch封装,会直接抛出,可通过查看日志判断任务是否执行完成

总结

但是本人真实操作得出:
#submit(task) 对task里的异常无法抛出,只是停止执行任务,无法报任何异常

public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(30);
        pool.submit(new Runnable() {
        @Override
        public void run() {
            int i = 1 / 0;
            System.out.println("submit Thread");
        }
    });
       /* pool.execute(new Runnable() {
            @Override
            public void run() {
                int i=1/0;
                System.out.println("excute Thread");
            }
        });*/
    }

执行完这段代码,控制台输出如下:
控制台输出
#execute(task) 对task里的异常会抛出,可以明确得知任务执行失败

 public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(30);
        /*pool.submit(new Runnable() {
            @Override
            public void run() {
                int i = 1 / 0;
                System.out.println("submit Thread");
            }
        });*/
        pool.execute(new Runnable() {
            @Override
            public void run() {
                int i=1/0;
                System.out.println("excute Thread");
            }
        });
    }

执行这段代码时,控制台如下:
控制台输出信息

原因解析:
因为submit()方法中,对task抛出的异常进行了catch封装

             try{
               excute(task);
            }catch(Exception e){
             tt=e;
             }

强制将异常捕捉封装并赋值给内置对象,所以没有抛出

而execute(task) 方法中并没有捕捉封装,直接将异常抛出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值