ThreadPoolExecutor execute 和 submit


ThreadPoolExecutor 除了execute 方法用來提交任務,還有submit 方法,他們的區別就是后者有返回值,其原理是在前者的基礎上使用了Future 接口。因此,我之前的示例改用submit 方法來實現會更加簡單。原因有二:

1、submit 方法提交的任務有返回值,方便判斷每個任務的最終運行結果,無需引入狀態標識變量
2、future 的get方法是阻塞的,無需引入CountDownLatch 並發包工具也可以等待所有線程運行完畢

直接上代碼

package com.yzy.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main2 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 線程安全的計數器
        AtomicInteger totalRows = new AtomicInteger(0);

        // 創建線程池,其中核心線程10,也是我期望的最大並發數,最大線程數和隊列大小都為30,即我的總任務數
        ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 30, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(30));

        // 創建 Future 集合,用來存儲Future 實例
        List<Future<Integer>> futureList = new ArrayList<>();

        for (int i = 0; i < 30; i++) {
            final int index = i;
            // 這里創建 Callable 實例,返回整型
            Future<Integer> future = executor.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    // 模擬異常的線程,返回0
                    if (index % 5 == 0) {
                        return 0;
                    }

                    int times = 0;
                    boolean loop = true;
                    // 模擬數據拉取過程可能需要分頁
                    while (loop) {
                        // 模擬每個任務需要分頁5次
                        if (times >= 5) {
                            break;
                        }
                        times++;

                        // 模擬計數
                        totalRows.incrementAndGet();
                        // 模擬耗時
                        try {
                            // 打印運行情況
                            System.out.println(Thread.currentThread().getName() + ":" + index + ":" + times);
                            Thread.sleep(Long.valueOf(String.valueOf(new Double(Math.random() * 1000).intValue())));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 成功返回1
                    return 1;
                }
            });

            futureList.add(future);
        }

        // 標記多線程關閉,但不會立馬關閉
        executor.shutdown();

        boolean flag = true;
        for (Future<Integer> future : futureList) {
            // 獲取每一個線程的返回結果,如果該線程未完成,會阻塞
            if (future.get() == 0) {
                flag = false;
            }
        }

        if (flag) {
            System.out.println("全部成功了,計數:" + totalRows.get());
        } else {
            System.out.println("失敗了");
        }
    }
}

運行結果

//省略若干行
pool-1-thread-7:24:5
pool-1-thread-3:29:3
pool-1-thread-3:29:4
pool-1-thread-5:28:3
pool-1-thread-6:26:4
pool-1-thread-6:26:5
pool-1-thread-5:28:4
pool-1-thread-5:28:5
pool-1-thread-3:29:5
失敗了

然后注釋這部分代碼

if (index % 5 == 0) {
    return 0;
}

再次運行:

//省略若干行
pool-1-thread-7:24:4
pool-1-thread-7:24:5
pool-1-thread-1:26:5
pool-1-thread-8:25:4
pool-1-thread-8:25:5
pool-1-thread-3:29:4
pool-1-thread-3:29:5
全部成功了,計數:150

鏈接:https://www.jianshu.com/p/4060dd274dbd


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM