异步获取有顺序的结果

FutureListTest

package com.xiaobu.juc;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

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

/**
 * The type Future list test.
 *
 * @author xiaobu
 * @className FutureListTest.java
 * @createTime 2022年06月30日 13:54:00
 */
@Slf4j
public class FutureListTest {
    /**
     * {@link FutureTask#get() 获取任务的执行结果}
     *
     * @param args the input arguments
     */
    @SneakyThrows
    public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("test");
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        // ThreadPoolExecutor threadPoolExecutor = ParallelUtils.newFixedThreadPool(3);
        // 不建议使用Executors创建
        ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
        Future<List<String>> future1 = threadPoolExecutor.submit(() ->
                {
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                },
                list.subList(0, 2));
        Future<List<String>> future2 = threadPoolExecutor.submit(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, list.subList(2, 4));
        Future<List<String>> future3 = threadPoolExecutor.submit(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, list.subList(4, 5));
        List<Future<List<String>>> futures = new ArrayList<>();
        futures.add(future1);
        futures.add(future2);
        futures.add(future3);
        for (Future<List<String>> future : futures) {
            System.out.println("future.get() = " + future.get());
        }
        threadPoolExecutor.shutdown();
        stopWatch.stop();
        System.out.println("耗时 = " + stopWatch.getTotalTimeMillis());
    }


}

    /**
     * Awaits completion or aborts on interrupt or timeout.
     *
     * @param timed true if use timed waits
     * @param nanos time to wait, if timed
     * @return state upon completion
     */
    private int awaitDone(boolean timed, long nanos)
        throws InterruptedException {
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        WaitNode q = null;
        boolean queued = false;
        for (;;) {
            if (Thread.interrupted()) {
                removeWaiter(q);
                throw new InterruptedException();
            }
         //1. 读取状态
        //1.1 如果s > COMPLETING,表示任务已经执行结束,或者发生异常结束了,就不会阻塞,直接返回
            int s = state;
            if (s > COMPLETING) {
                if (q != null)
                    q.thread = null;
                return s;
            }
            else if (s == COMPLETING) // cannot time out yet
                    /**
     * 当前线程从执行状态(运行状态)变为可执行态(就绪状态)
     * 就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,让自己或者其它的线程运行。
     *
     * 打个比方:现在有很多人在排队上厕所,好不容易轮到这个人上厕所了,突然这个人说:“我要和大家来个竞赛,看谁先抢到厕所!”,然后所有的人在同一起跑线冲向厕所,有可能是别人抢到了,也有可能他自己有抢到了。我们还知道线程有个优先级的问题,那么手里有优先权的这些人就一定能抢到厕所的位置吗? 不一定的,他们只是概率上大些,也有可能没特权的抢到了。
     */
                Thread.yield();
            else if (q == null)
                q = new WaitNode();
            else if (!queued)
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                     q.next = waiters, q);
            else if (timed) {
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L) {
                    removeWaiter(q);
                    return state;
                }
                LockSupport.parkNanos(this, nanos);
            }
            else
                LockSupport.park(this);
        }
    }

InvokeAllTest

package com.xiaobu.juc;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

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

/**
 * @author xiaobu
 * @className InvokeAllTest.java
 * @createTime 2022年06月30日 13:54:00
 */
@Slf4j
public class InvokeAllTest {
    /**
     * {@link AbstractExecutorService#invokeAll(Collection)} () }
     *
     * @param args the input arguments
     */
    @SneakyThrows
    public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("test");
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        List<String> mList;
        ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
        // 不建议使用Executors创建
        // ThreadPoolExecutor threadPoolExecutor = ParallelUtils.newFixedThreadPool(3);
        Callable<List<String>> task1 = () -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return list.subList(0, 2);
        };
        Callable<List<String>> task2 = () -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return list.subList(2, 4);
        };
        Callable<List<String>> task3 = () -> list.subList(4, 5);
        List<Callable<List<String>>> taskList = new ArrayList<>();
        taskList.add(task1);
        taskList.add(task2);
        taskList.add(task3);
        List<Future<List<String>>> futures = threadPoolExecutor.invokeAll(taskList);
        for (Future<List<String>> future : futures) {
            mList = future.get();
            mList.forEach(System.out::println);
        }
        threadPoolExecutor.shutdown();
        stopWatch.stop();
        System.out.println("耗时 = " + stopWatch.getTotalTimeMillis());
    }


}

可取消的异步任务——FutureTask用法及解析

AllOfTest

package com.xiaobu.juc;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

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

/**
 * The type Future list test.
 *
 * @author xiaobu
 * @className FutureListTest.java
 * @createTime 2022年06月30日 13:54:00
 */
@Slf4j
public class AllOfTest {
    /**
     * {@link FutureTask#get() 获取任务的执行结果}
     *
     * @param args the input arguments
     */
    @SneakyThrows
    public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("test");
        test();
        stopWatch.stop();
        System.out.println("耗时 = " + stopWatch.getTotalTimeMillis());
    }

    private static void test() throws InterruptedException, ExecutionException {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("submit");
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        // 不建议使用Executors创建
        ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
        Map<String, Integer> resultMap = getThreadSizeAndThreadNum(list);
        Integer threadSize = resultMap.get("threadSize");
        Integer threadNum = resultMap.get("threadNum");
        List<String> mList;
        List<CompletableFuture<List<String>>> dataList = new ArrayList<>();
        int j = 5;
        for (int i = 0; i < threadNum; i++) {
            if (i == threadNum - 1) {
                mList = list.subList(i * threadSize, list.size());
            } else {
                mList = list.subList(i * threadSize, (i + 1) * threadSize);
            }
            List<String> finalList = mList;
            int finalI = i;
            CompletableFuture<List<String>> completableFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    int k = j - finalI;
                    // 模拟操作
                    TimeUnit.SECONDS.sleep(k);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                return finalList;
            }, threadPoolExecutor);
            dataList.add(completableFuture);
        }
        CompletableFuture[] completableFutures = dataList.toArray(new CompletableFuture[0]);
        // allOf里面有个andTree方法 等所有任务执行完成后按放入的顺序输出结果
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(completableFutures);
        List<String> result = new ArrayList<>();
        // List<List<String>> lists = voidCompletableFuture.thenApply(v -> dataList.stream().map(completableFuture -> {
        //     try {
        //         return completableFuture.get();
        //     } catch (InterruptedException | ExecutionException e) {
        //         e.printStackTrace();
        //     }
        //     return null;
        // }).collect(Collectors.toList())).get();
        // log.info("【test】::lists ==> 【{}】", lists);
        // Stream<List<String>> listStream = voidCompletableFuture.thenApply(v -> dataList.stream().map(completableFuture -> {
        //     try {
        //         return completableFuture.get();
        //     } catch (InterruptedException | ExecutionException e) {
        //         e.printStackTrace();
        //     }
        //     return null;
        // })).get();
        // 在这里阻塞
        voidCompletableFuture.whenComplete((v, e) -> {
            System.out.println("allOf complete");
        }).get();
        stopWatch.stop();
        stopWatch.start("for");
        for (CompletableFuture<List<String>> completableFuture : dataList) {
            List<String> strings = completableFuture.get();
            result.addAll(strings);
        }
        result.forEach(System.out::println);
        stopWatch.stop();
        System.out.println("stopWatch.prettyPrint() = " + stopWatch.prettyPrint());
        threadPoolExecutor.shutdown();
    }

    public static Map<String, Integer> getThreadSizeAndThreadNum(List<String> subList) {
        int threadSize = 1;
        int threadNum = 0;
        if (subList.size() <= 1) {
            threadNum = subList.size();
        }
        if (subList.size() > 1) {
            threadSize = 2;
            threadNum = subList.size() % threadSize == 0 ? subList.size() / threadSize : subList.size() / threadSize + 1;
        }
        Map<String, Integer> map = new HashMap<>(4);
        map.put("threadSize", threadSize);
        map.put("threadNum", threadNum);
        return map;
    }

}

参考:

CompletableFuture 组合处理 allOf 和 anyOf太赞了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值