并行多线程任务的创建

7 篇文章 0 订阅

对于简单的并行任务,可以通过“线程池+Future”的方案来 解决;如果任务之间有聚合关系,无论是AND聚合还是OR聚合,都可以通过CompletableFuture来解决;而批量的并行任务,则可以通过CompletionService来解决

线程池+Future (带返回值,即主线程可以获取子线程的结果,无需获取结果可以去掉Future)

        // 线程池
ExecutorService myExecutor = new ThreadPoolExecutor(4,5,1000L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(100));

        Future<Integer> f1 = myExecutor.submit(()->{
            Thread.sleep(2000);
            System.out.println("a");
            return 1;
        });
        Future<Integer> f2 = myExecutor.submit(()->{
            Thread.sleep(3000);
            System.out.println("b");
            return 2;
        });
        Future<Integer> f3 = myExecutor.submit(()->{
            Thread.sleep(1000);
            System.out.println("c");
            return 3;
        });
        //主线程阻塞等待线程的结果
        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());

线程池+FutureTask

FutureTask<Integer> ft1 = new FutureTask<>(() -> {
    Thread.sleep(3000);
    System.out.println("1111");
    return 1;
});
FutureTask<Integer> ft2 = new FutureTask<>(() -> {
    Thread.sleep(2000);
    System.out.println("2222");
    return 2;
});
FutureTask<Integer> ft3 = new FutureTask<>(() -> {
    Thread.sleep(1000);
    System.out.println("3333");
    return 3;
});
myExecutor.submit(ft1);
myExecutor.submit(ft2);
myExecutor.submit(ft3);

Integer result = ft1.get();
System.out.println(result);
Integer result2 = ft2.get();
System.out.println(result2);
Integer result3 = ft3.get();
System.out.println(result3);

线程池+ CompletableFuture

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureTest {

    public static void main(String[] args) {

        // 起10个线程的线程池
        ExecutorService myExecutor = Executors.newFixedThreadPool(10);
        Long startTIME = System.currentTimeMillis();

        /* 任务一 */
        //无返回值得方法 runAsync
        CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(1000);
                Long endTIME = System.currentTimeMillis();
                Long elapsedTime = endTIME - startTIME;
                System.out.println("任务一 elapsedTime="+elapsedTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }, myExecutor);


        /* 任务二 :与任务一为并行关系*/
        //有返回值的方法 supplyAsync
        CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> {
            Integer result2 = 2;
            try {
                Thread.sleep(4000);
                Long endTIME = System.currentTimeMillis();
                Long elapsedTime = endTIME - startTIME;
                System.out.println("任务二 elapsedTime="+elapsedTime + "; result="+ result2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return result2;
        }, myExecutor);

        /* 任务三 :与任务一为并行关系*/
        //有返回值的方法 supplyAsync
        CompletableFuture<Integer> cf3 = CompletableFuture.supplyAsync(() -> {
            Integer result3 = 1;
            try {
                Thread.sleep(2000);
                Long endTIME = System.currentTimeMillis();
                Long elapsedTime = endTIME - startTIME;
                System.out.println("任务三 elapsedTime="+elapsedTime + "; result="+ result3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return result3;
        }, myExecutor);


        /**                                    汇聚任务                           **/

        /* 任务四 (AND汇聚): 任务一 和 任务二都完成后才开始 */
        CompletableFuture<Integer> cf4 = cf2.thenCombine(cf1, (result2,__)->{
            Integer result4 = result2;
            Long endTIME = System.currentTimeMillis();
            Long elapsedTime = endTIME - startTIME;
            System.out.println("任务四 elapsedTime="+elapsedTime);
            return result4;
        });

        /* 任务五 (AND汇聚): 任务二 和 任务三都完成后才开始 */
        CompletableFuture<Integer> cf5 = cf2.thenCombine(cf3, (result2,result3)->{
            Integer result5 = result2+result3;
            Long endTIME = System.currentTimeMillis();
            Long elapsedTime = endTIME - startTIME;
            System.out.println("任务五 elapsedTime="+elapsedTime );
            return result5;
        });

        /* 任务六 (OR汇聚): 任务二 或 任务三 其中一个完成了就开始执行 */
        CompletableFuture<Integer> cf6 = cf2.applyToEither(cf3, result -> {
            Integer result6 = result;
            Long endTIME = System.currentTimeMillis();
            Long elapsedTime = endTIME - startTIME;
            System.out.println("任务六 elapsedTime="+elapsedTime);
            return result6;
        });


        System.out.println("任务四 result :"+cf4.join());
        System.out.println("任务五 result :"+cf5.join());
        System.out.println("任务六 result :"+cf6.join());


    }
}
任务一 elapsedTime=1053
任务三 elapsedTime=2054; result=1
任务六 elapsedTime=2054
任务二 elapsedTime=4053; result=2
任务五 elapsedTime=4053
任务四 elapsedTime=4053
任务四 result :2
任务五 result :3
任务六 result :1

线程池+CompletionService

以下使用场景可以使用 CompletionService 来实现

1、多个任务并发执行,先完成的任务执行下一步骤。

2、相同任务分给多个线程并发执行,其中一个返回结果就结束剩余的所有任务


import java.util.concurrent.*;

public class CompletionServiceTest {
    public static void main(String[] args) {
        ExecutorService myExecutor = Executors.newFixedThreadPool(10);
        Long startTIME = System.currentTimeMillis();

        // 创建CompletionService
        CompletionService<Integer> completionService = new ExecutorCompletionService<>(myExecutor);

        completionService.submit(()->{
            Thread.sleep(3000);
            Long endTIME = System.currentTimeMillis();
            Long elapsedTime = endTIME - startTIME;
            System.out.println("任务一 elapsedTime=" + elapsedTime);
            return 1;
        });

        completionService.submit(()->{
            Thread.sleep(1000);
            Long endTIME = System.currentTimeMillis();
            Long elapsedTime = endTIME - startTIME;
            System.out.println("任务二 elapsedTime=" + elapsedTime);
            return 2;
        });

        completionService.submit(()->{
            Thread.sleep(2000);
            Long endTIME = System.currentTimeMillis();
            Long elapsedTime = endTIME - startTIME;
            System.out.println("任务三 elapsedTime=" + elapsedTime);
            return 3;
        });

        for(int i =0 ; i<3;i++) {
            try{
                Future<Integer> future= completionService.take();
                Integer r = future.get();
                System.out.println("任务结果=" + r);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("任务结束" );
    }
}
任务二 elapsedTime=1050
任务结果=2
任务三 elapsedTime=2050
任务结果=3
任务一 elapsedTime=3050
任务结果=1
任务结束

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值