Java 线程池execute和submit的区别

execute和submit的区别

方法 使用场景 是否有返回值 异常处理
execute 适用于不需要返回值的场景 线程内部如果发生异常,主线程无感知。异常会通过stdout方式显示,如果需要在日志中打印,需要单独设置。方法见示例3
submit 适用于需要获取返回值的场景 调用future get方法时,异常会抛出。如果不调用get方法,则无法获取。

示例1:execute使用

  private static void executeDemo() {
    Runnable runnable = ()-> {
      System.out.println("thread execute");
    };

    ExecutorService executorService = Executors.newFixedThreadPool(2);
    executorService.execute(runnable);

    executorService.shutdown();
  }

输出:

thread execute

示例2:submit使用

  private static void submitDemo() throws Exception {
    Callable<String> call = ()-> {
      System.out.println("thread submit");
      return "hello";
    };

    ExecutorService executorService = Executors.newFixedThreadPool(2);
    Future<String> future = executorService.submit(call);

    String output = future.get();

    System.out.println("output : " + output);
    executorService.shutdown();
  }

输出:

thread submit
output : hello

示例3:execute,线程内部抛出异常,并打印出相关结果

  private static void executeException2Demo() {
    Runnable runnable = ()-> {
      System.out.println("thread execute before exception");
      throw new RuntimeException("test exception");
    };

    ThreadFactory threadFactory = r -> {
      Thread thread = Executors.defaultThreadFactory().newThread(r);
      thread.setUncaughtExceptionHandler((t,e) -> {
        System.err.println("catch exception for execute : " + e.getMessage());
      });
      return thread;
    };

    ExecutorService executorService = Executors.newFixedThreadPool(2, threadFactory);
    executorService.execute(runnable);

    executorService.shutdown();
  }

输出:

thread execute before exception
catch exception for execute : test exception

备注:
如果需要捕获excute时的异常,需要通过线程的setUncaughtExceptionHandler方法来设置。

示例4: submit,线程内部抛出异常,并打印出相关结果

  private static void submitExecptionDemo() throws Exception {
    Callable<String> call = ()-> {
      System.out.println("thread submit before exception");
      throw new RuntimeException("test submit exception");
    };

    ExecutorService executorService = Executors.newFixedThreadPool(2);
    Future<String> future = executorService.submit(call);

    try {
      String output = future.get();

      System.out.println("output : " + output);
    } catch (Exception e) {
      System.err.println("catch exception:" + e.getMessage());
    }

    executorService.shutdown();
  }

输出:

thread submit before exception
catch exception:java.lang.RuntimeException: test submit exception

备注:

  1. 异常是调用get方法时抛出的。
  2. 没有调用get方法时,即使线程已经允许完了,异常也不会抛出。
上一篇:教你远程Debug Spark


下一篇:Python爬虫练习(三)