Google Guava ListeningExecutorService

POM

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>29.0-jre</version>
</dependency>
package com.vipsoft;


import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.*;

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


public class ListeningExecutorTest {


    /**
     * 線程池
     */
    static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 10, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(200),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    /**
     * 數據處理
     *
     * @return
     * @throws Exception
     */

    public static void main(String[] args) throws Exception {
        List<String> result = new ArrayList<>();
        List<String> list = new ArrayList<>();

        //模擬原始數據
        for (int i = 0; i < 1211; i++) {
            list.add(i + "-");
            System.out.println("添加原始數據:" + i);
        }

        int size = 50;//切分粒度,每size條數據,切分一塊,交由一條線程處理
        int countNum = 0;//當前處理到的位置
        int count = list.size() / size;//切分塊數
        int threadNum = 0;//使用線程數
        if (count * size != list.size()) {
            count++;
        }

        final CountDownLatch countDownLatch = new CountDownLatch(count);

        //使用Guava的ListeningExecutorService裝飾線程池
        ListeningExecutorService executorService = MoreExecutors.listeningDecorator(threadPoolExecutor);

        while (countNum < count * size) {
            //切割不同的數據塊,分段處理
            threadNum++;
            countNum += size;
            MyCallable myCallable = new MyCallable();
            myCallable.setList(ImmutableList.copyOf(list.subList(countNum - size, list.size() > countNum ? countNum : list.size())));

            ListenableFuture listenableFuture = executorService.submit(myCallable);


            //回調函數
            Futures.addCallback(listenableFuture, new FutureCallback<List<String>>() {
                //任務處理成功時執行
                @Override
                public void onSuccess(List<String> list) {
                    countDownLatch.countDown();
                    System.out.println("第h次處理完成");
                    result.addAll(list);
                }

                //任務處理失敗時執行
                @Override
                public void onFailure(Throwable throwable) {
                    countDownLatch.countDown();
                    System.out.println("處理失敗:" + throwable);
                }
            },executorService );

        }

        //設置時間,超時了直接向下執行,不再阻塞
        countDownLatch.await(3, TimeUnit.SECONDS);

        result.stream().forEach(s -> System.out.println(s));
        System.out.println("------------結果處理完畢,返回完畢,使用線程數量:" + threadNum);
    }


    static class MyCallable implements Callable {

        private List<String> list;

        @Override
        public Object call() throws Exception {
            List<String> listReturn = new ArrayList<>();
            //模擬對數據處理,然後返回
            for (int i = 0; i < list.size(); i++) {
                listReturn.add(list.get(i) + ":處理時間:" + System.currentTimeMillis() + "---:處理線程:" + Thread.currentThread());
            }

            return listReturn;
        }

        public void setList(List<String> list) {
            this.list = list;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章