zoukankan      html  css  js  c++  java
  • ThreadPoolExecutor的execute()和submit()方法

    ThreadPoolExecutor的execute()和submit()方法

    我希望使用多线程执行一个运算,并且线程执行完毕后我要获取执行结果。其实使用线程池ThreadPoolExecutor的execute()和submit()方法都可以。

    使用execute()的话,事先定义一个存放返回结果的集合,开辟线程时,将集合的元素作为参数代入自定义的Runnable接口的实现类中,多线程执行完毕后遍历集合即可获得运算结果。

    使用submit()的话,可以在submit()中执行一个Callable接口的实现类,submit()方法可以返回一个Future<> future,然后使用future.get()方法获得返回结果,由于future.get()会使调用线程池的线程阻塞,等待返回结果,所以可以先将Future<> future放入一个集合,等多线程执行完毕后再遍历集合获得运算结果。

    使用execute()方法:

    定义一个结果类:

    1.  
      public class RunResult {
    2.  
      // 输入参数
    3.  
      private Integer param;
    4.  
      // 是否运算成功
    5.  
      private Boolean success;
    6.  
      // 运算结果
    7.  
      private Integer result;
    8.  
      public Integer getParam() {
    9.  
      return param;
    10.  
      }
    11.  
      public void setParam(Integer param) {
    12.  
      this.param = param;
    13.  
      }
    14.  
      public Boolean getSuccess() {
    15.  
      return success;
    16.  
      }
    17.  
      public void setSuccess(Boolean success) {
    18.  
      this.success = success;
    19.  
      }
    20.  
      public Integer getResult() {
    21.  
      return result;
    22.  
      }
    23.  
      public void setResult(Integer result) {
    24.  
      this.result = result;
    25.  
      }
    26.  
      }

    定义一个Runnable接口的实现类:

    1.  
      public class MyRunnable implements Runnable {
    2.  
      // 运算结果类
    3.  
      private RunResult result;
    4.  
      // 线程同步器
    5.  
      private CountDownLatch main;
    6.  
      @Override
    7.  
      public void run() {
    8.  
      String name = Thread.currentThread().getName();
    9.  
      System.out.println(name + " 线程开始执行" + "-" + result.getParam());
    10.  
      for (int i = 0; i < 1; i++) {
    11.  
      for (int j = 1; j <= 200000000; j++) {
    12.  
      if (j == 200000000 && null != result.getParam()) {
    13.  
      result.setResult(result.getParam()*10);
    14.  
      result.setSuccess(true);
    15.  
      System.out.println(name + " 线程正在进行计算" + "-" + result.getParam());
    16.  
      } else {
    17.  
      result.setSuccess(false);
    18.  
      }
    19.  
      }
    20.  
      }
    21.  
      System.out.println(name + " 线程执行完毕" + "-" + result.getParam());
    22.  
      main.countDown();
    23.  
      }
    24.  
      public MyRunnable(RunResult result, CountDownLatch main) {
    25.  
      super();
    26.  
      this.result = result;
    27.  
      this.main = main;
    28.  
      }
    29.  
      public MyRunnable() {
    30.  
      super();
    31.  
      }
    32.  
      }

    main方法:

    1.  
      public static void main(String[] args) {
    2.  
      ThreadPoolExecutor threadPool = new ThreadPoolExecutor(6, 10, 10L, TimeUnit.SECONDS,
    3.  
      new LinkedBlockingQueue<Runnable>(20),
    4.  
      Executors.defaultThreadFactory(),
    5.  
      new ThreadPoolExecutor.CallerRunsPolicy());
    6.  
      // 存放结果类的集合
    7.  
      List<RunResult> list = new ArrayList<RunResult>(12);
    8.  
      // 线程同步器
    9.  
      CountDownLatch main = new CountDownLatch(12);
    10.  
      for (int i = 1; i <= 12; i++) {
    11.  
      RunResult result = new RunResult();
    12.  
      result.setParam(i);
    13.  
      list.add(result);
    14.  
      MyRunnable runnable = new MyRunnable(result,main);
    15.  
      threadPool.execute(runnable);
    16.  
      }
    17.  
      try {
    18.  
      main.await();
    19.  
      System.out.println(JSON.toJSON(list));
    20.  
      // 线程池不用了,关闭线程池
    21.  
      threadPool.shutdown();
    22.  
      //threadPool.shutdownNow();
    23.  
      } catch (InterruptedException e) {
    24.  
       
    25.  
      }
    26.  
      }

    执行结果:

    1.  
      pool-1-thread-1 线程开始执行-1
    2.  
      pool-1-thread-5 线程开始执行-5
    3.  
      pool-1-thread-3 线程开始执行-3
    4.  
      pool-1-thread-2 线程开始执行-2
    5.  
      pool-1-thread-4 线程开始执行-4
    6.  
      pool-1-thread-6 线程开始执行-6
    7.  
      pool-1-thread-1 线程正在进行计算-1
    8.  
      pool-1-thread-1 线程执行完毕-1
    9.  
      pool-1-thread-1 线程开始执行-7
    10.  
      pool-1-thread-6 线程正在进行计算-6
    11.  
      pool-1-thread-6 线程执行完毕-6
    12.  
      pool-1-thread-6 线程开始执行-8
    13.  
      pool-1-thread-5 线程正在进行计算-5
    14.  
      pool-1-thread-5 线程执行完毕-5
    15.  
      pool-1-thread-5 线程开始执行-9
    16.  
      pool-1-thread-3 线程正在进行计算-3
    17.  
      pool-1-thread-3 线程执行完毕-3
    18.  
      pool-1-thread-3 线程开始执行-10
    19.  
      pool-1-thread-4 线程正在进行计算-4
    20.  
      pool-1-thread-4 线程执行完毕-4
    21.  
      pool-1-thread-4 线程开始执行-11
    22.  
      pool-1-thread-2 线程正在进行计算-2
    23.  
      pool-1-thread-2 线程执行完毕-2
    24.  
      pool-1-thread-2 线程开始执行-12
    25.  
      pool-1-thread-5 线程正在进行计算-9
    26.  
      pool-1-thread-5 线程执行完毕-9
    27.  
      pool-1-thread-4 线程正在进行计算-11
    28.  
      pool-1-thread-4 线程执行完毕-11
    29.  
      pool-1-thread-2 线程正在进行计算-12
    30.  
      pool-1-thread-2 线程执行完毕-12
    31.  
      pool-1-thread-6 线程正在进行计算-8
    32.  
      pool-1-thread-3 线程正在进行计算-10
    33.  
      pool-1-thread-3 线程执行完毕-10
    34.  
      pool-1-thread-1 线程正在进行计算-7
    35.  
      pool-1-thread-6 线程执行完毕-8
    36.  
      pool-1-thread-1 线程执行完毕-7
    37.  
      [{"result":10,"param":1,"success":true},{"result":20,"param":2,"success":true},{"result":30,"param":3,"success":true},{"result":40,"param":4,"success":true},{"result":50,"param":5,"success":true},{"result":60,"param":6,"success":true},{"result":70,"param":7,"success":true},{"result":80,"param":8,"success":true},{"result":90,"param":9,"success":true},{"result":100,"param":10,"success":true},{"result":110,"param":11,"success":true},{"result":120,"param":12,"success":true}]

    使用submit()方法:

    返回结果类同上

    定义一个Callable接口的实现类:

    1.  
      public class MyCallable implements Callable<RunResult> {
    2.  
      // 运算结果类
    3.  
      private RunResult result;
    4.  
      // 线程同步器
    5.  
      private CountDownLatch main;
    6.  
      @Override
    7.  
      public RunResult call() throws Exception {
    8.  
      String name = Thread.currentThread().getName();
    9.  
      System.out.println(name + " 线程开始执行" + "-" + result.getParam());
    10.  
      for (int i = 0; i < 1; i++) {
    11.  
      for (int j = 1; j <= 200000000; j++) {
    12.  
      if (j == 200000000 && null != result.getParam()) {
    13.  
      result.setResult(result.getParam()*10);
    14.  
      result.setSuccess(true);
    15.  
      System.out.println(name + " 线程正在进行计算" + "-" + result.getParam());
    16.  
      } else {
    17.  
      result.setSuccess(false);
    18.  
      }
    19.  
      }
    20.  
      }
    21.  
      System.out.println(name + " 线程执行完毕" + "-" + result.getParam());
    22.  
      main.countDown();
    23.  
      return result;
    24.  
      }
    25.  
      public MyCallable(RunResult result, CountDownLatch main) {
    26.  
      super();
    27.  
      this.result = result;
    28.  
      this.main = main;
    29.  
      }
    30.  
      public MyCallable() {
    31.  
      super();
    32.  
      }
    33.  
      }

    main方法:

    1.  
      public static void main(String[] args) {
    2.  
      ThreadPoolExecutor threadPool = new ThreadPoolExecutor(6, 10, 10L, TimeUnit.SECONDS,
    3.  
      new LinkedBlockingQueue<Runnable>(20),
    4.  
      Executors.defaultThreadFactory(),
    5.  
      new ThreadPoolExecutor.CallerRunsPolicy());
    6.  
      // 存放Future<>的集合
    7.  
      List<Future<RunResult>> list = new ArrayList<Future<RunResult>>(12);
    8.  
      // 线程同步器
    9.  
      CountDownLatch main = new CountDownLatch(12);
    10.  
      for (int i = 1; i <= 12; i++) {
    11.  
      RunResult result = new RunResult();
    12.  
      result.setParam(i);
    13.  
      MyCallable callable = new MyCallable(result,main);
    14.  
      Future<RunResult> runResultFuture = threadPool.submit(callable);
    15.  
      list.add(runResultFuture);
    16.  
      }
    17.  
      try {
    18.  
      main.await();
    19.  
      for (int i = 0; i < list.size(); i++) {
    20.  
      RunResult runResult = list.get(i).get();
    21.  
      System.out.println(JSON.toJSON(runResult));
    22.  
      }
    23.  
      // 线程池不用了,关闭线程池
    24.  
      threadPool.shutdown();
    25.  
      //threadPool.shutdownNow();
    26.  
      } catch (InterruptedException e) {
    27.  
       
    28.  
      } catch (ExecutionException e) {
    29.  
       
    30.  
      }
    31.  
      }

    执行结果:

    1.  
      pool-1-thread-3 线程开始执行-3
    2.  
      pool-1-thread-4 线程开始执行-4
    3.  
      pool-1-thread-2 线程开始执行-2
    4.  
      pool-1-thread-1 线程开始执行-1
    5.  
      pool-1-thread-5 线程开始执行-5
    6.  
      pool-1-thread-6 线程开始执行-6
    7.  
      pool-1-thread-1 线程正在进行计算-1
    8.  
      pool-1-thread-3 线程正在进行计算-3
    9.  
      pool-1-thread-5 线程正在进行计算-5
    10.  
      pool-1-thread-5 线程执行完毕-5
    11.  
      pool-1-thread-2 线程正在进行计算-2
    12.  
      pool-1-thread-2 线程执行完毕-2
    13.  
      pool-1-thread-6 线程正在进行计算-6
    14.  
      pool-1-thread-6 线程执行完毕-6
    15.  
      pool-1-thread-4 线程正在进行计算-4
    16.  
      pool-1-thread-4 线程执行完毕-4
    17.  
      pool-1-thread-6 线程开始执行-9
    18.  
      pool-1-thread-5 线程开始执行-7
    19.  
      pool-1-thread-2 线程开始执行-8
    20.  
      pool-1-thread-3 线程执行完毕-3
    21.  
      pool-1-thread-3 线程开始执行-11
    22.  
      pool-1-thread-1 线程执行完毕-1
    23.  
      pool-1-thread-1 线程开始执行-12
    24.  
      pool-1-thread-4 线程开始执行-10
    25.  
      pool-1-thread-6 线程正在进行计算-9
    26.  
      pool-1-thread-5 线程正在进行计算-7
    27.  
      pool-1-thread-5 线程执行完毕-7
    28.  
      pool-1-thread-1 线程正在进行计算-12
    29.  
      pool-1-thread-1 线程执行完毕-12
    30.  
      pool-1-thread-4 线程正在进行计算-10
    31.  
      pool-1-thread-2 线程正在进行计算-8
    32.  
      pool-1-thread-3 线程正在进行计算-11
    33.  
      pool-1-thread-6 线程执行完毕-9
    34.  
      pool-1-thread-3 线程执行完毕-11
    35.  
      pool-1-thread-2 线程执行完毕-8
    36.  
      pool-1-thread-4 线程执行完毕-10
    37.  
      {"result":10,"param":1,"success":true}
    38.  
      {"result":20,"param":2,"success":true}
    39.  
      {"result":30,"param":3,"success":true}
    40.  
      {"result":40,"param":4,"success":true}
    41.  
      {"result":50,"param":5,"success":true}
    42.  
      {"result":60,"param":6,"success":true}
    43.  
      {"result":70,"param":7,"success":true}
    44.  
      {"result":80,"param":8,"success":true}
    45.  
      {"result":90,"param":9,"success":true}
    46.  
      {"result":100,"param":10,"success":true}
    47.  
      {"result":110,"param":11,"success":true}
    48.  
      {"result":120,"param":12,"success":true}

    参考博客:ThreadPoolExecutor中的submit()方法详细讲解

     
  • 相关阅读:
    函数式编程笔记
    Java时间类总结
    【问题记录】MySQL中时间戳转日期格式和Java中时间戳转日期格式偶尔不一致
    Java 注解
    Java编程思想之十 内部类
    Java编程思想之九 接口
    Java编程思想之八多态
    Java编程思想之七复用类
    Java编程思想之六访问权限控制
    Java编程思想之五初始化与清理
  • 原文地址:https://www.cnblogs.com/xiondun/p/15296456.html
Copyright © 2011-2022 走看看