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()方法详细讲解

 
原文地址:https://www.cnblogs.com/xiondun/p/15296456.html