线程池学习(二)execute() 和 submit() 的区别

转载:线程池

线程提交的两种方式

 ExecutorService poll3 = Executors.newCachedThreadPool();
        for (int i = 0; i < 2; i++) {
            poll3.execute(new TargetTask());
            poll3.submit(new TargetTask());
        }
  1. execute方法
    void execute(Runnable command): Executor接口中的方法
  2. submit方法
    Future submit(Callable task);
    Future submit(Runnable task, T result);
    Future submit(Runnable task);
    这3个submit方法都是ExecutorService接口中的方法(ExecutorService接口 是Executor接口的子类)

区别

  1. execute 方法只能接收 Runnable 类型的参数, submit 方法可以接收 Runnable 和 Callable 两种类型的参数
  2. execute 方法没有返回值,submit 方法有返回值(原因是Callable 类型任务有返回值,Runnable 类型任务没有返回值)
  3. submit()方便子线程的异常处理
@Slf4j
public class ExecutorsTest {

    static class TargetTask implements Runnable {
        public static final int SLEEP_GAP = 1000;
        // AtomicInteger 提供了一种线程安全的方式来对整数进行操作。它可以保证多个线程同时对同一个AtomicInteger对象进行操作时,不会出现数据竞争和不一致的情况
        static AtomicInteger taskNo = new AtomicInteger(0);
        String taskName;

        @Override
        public void run() {
            log.info(taskName + "is running ...");
            try {
                Thread.sleep(SLEEP_GAP);
            } catch (Exception e) {
                log.error(taskName + "running error !");
                e.printStackTrace();
            }
            log.info(taskName + "is  end ...");

        }

        TargetTask() {
            taskName = "task_" + taskNo;
            taskNo.incrementAndGet();
        }
    }

    static class TargetTaskWithError extends TargetTask {
        public void run() {
            super.run();//执行父类的run方法
            // 强行抛出异常
            throw new RuntimeException("Error from " + taskName);
        }
    }
 public static void main(String[] args) throws InterruptedException {
  
 	ExecutorService poll6 = Executors.newFixedThreadPool(3);
        // execute 方式不关心任务执行的结果,没有返回值,不能处理异常
        try{
            poll6.execute(new TargetTaskWithError());
        }catch (Exception e){
            log.error("task has Exception !");
            e.printStackTrace();
        }

        // submit 方式有返回值,方便处理异常
//        Future future = poll6.submit(new TargetTaskWithError());
//        try {
//            if (null == future.get()) {
//                log.info(" task no Exception !");
//            }
//        } catch (Exception e) {
//        log.error("task has Exception !");
//            e.printStackTrace();
//        }

        poll6.shutdown();
    }
}

如图:
使用 submit 向线程池提交任务可以处理异常,打印了task has Exception !
线程池学习(二)execute() 和 submit() 的区别_第1张图片

使用 execute 向线程池提交任务不能处理异常,未打印了task has Exception !
线程池学习(二)execute() 和 submit() 的区别_第2张图片

你可能感兴趣的:(#,线程,java,开发语言,线程池)