Java多线程异步编程之:Futrue、FutureTask、CompletionService、CompletableFuture

代码:https://gitee.com/hsjjsh123/multi-thread.git

上结论:
在这里插入图片描述
demo为先,上代码:

一、Futrue:

package com.hsj.future;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author denny.zhang
 * @author HeShengjin 2356899074@qq.com
 * @ClassName: FutureDemo
 * @Description: Future多线程并发任务结果归集
 * @date 2016年11月4日 下午1:50:32
 */
public class FutureDemo {

    public static void main(String[] args) {
        Long start = System.currentTimeMillis();
        //开启多线程
        ExecutorService exs = Executors.newFixedThreadPool(10);
        try {
            //结果集
            List<Integer> list = new ArrayList<Integer>();
            List<Future<Integer>> futureList = new ArrayList<Future<Integer>>();
            //1.高速提交10个任务,每个任务返回一个Future入list
            for (int i = 0; i < 10; i++) {
                futureList.add(exs.submit(new CallableTask(i + 1)));
            }
            Long getResultStart = System.currentTimeMillis();
            System.out.println("结果归集开始时间=" + new Date());
            //2.结果归集,用迭代器遍历futureList,高速轮询(模拟实现了并发),任务完成就移除
            while (futureList.size() > 0) {
                Iterator<Future<Integer>> iterable = futureList.iterator();
                //遍历一遍
                while (iterable.hasNext()) {
                    Future<Integer> future = iterable.next();
                    //如果任务完成取结果,否则判断下一个任务是否完成
//                    if (future.isDone() && !future.isCancelled()){//非阻塞
                    //获取结果
                    Integer i = future.get();//阻塞
                    System.out.println("任务i=" + i + "获取完成,移出任务队列!" + new Date());
                    list.add(i);
                    //任务完成移除任务
                    iterable.remove();
//                    }else{
//                        Thread.sleep(1);//避免CPU高速运转,这里休息1毫秒,CPU纳秒级别
//                    }
                }
            }
            System.out.println("list=" + list);
            System.out.println("总耗时=" + (System.currentTimeMillis() - start) + ",取结果归集耗时=" + (System.currentTimeMillis() - getResultStart));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            exs.shutdown();
        }
    }
}
package com.hsj.future;

import java.util.Date;
import java.util.concurrent.Callable;

public class CallableTask implements Callable<Integer> {
    Integer i;

    public CallableTask(Integer i) {
        super();
        this.i = i;
    }

    @Override
    public Integer call() throws Exception {
        if (i == 1) {
            Thread.sleep(3000);//任务1耗时3秒
        } else if (i == 5) {
            Thread.sleep(5000);//任务5耗时5秒
        } else {
            Thread.sleep(1000);//其它任务耗时1秒
        }
        System.out.println("task线程:" + Thread.currentThread().getName() + "任务i=" + i + ",完成!"+ new Date());
        return i;
    }
}

二、FutureTask:

package com.hsj.futuretask;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 *
 * @ClassName:FutureTaskDemo
 * @Description:FutureTask实现多线程并发执行任务并取结果归集
 *              有点儿类似于Promise方式
 * @author diandian.zhang
 * @author HeShengjin 2356899074@qq.com
 * @date 2017年6月16日上午10:36:05
 */
public class FutureTaskDemo {

    public static void main(String[] args)  {
        Long start = System.currentTimeMillis();
        //开启多线程
        ExecutorService exs = Executors.newFixedThreadPool(10);
        try {
            //结果集
            List<Integer> list = new ArrayList<Integer>();
            List<FutureTask<Integer>> futureList = new ArrayList<FutureTask<Integer>>();
            //启动线程池,10个任务固定线程数为5
            for(int i=0;i<10;i++){
                FutureTask<Integer> futureTask = new FutureTask<Integer>(new CallableTask(i+1));
                //提交任务,添加返回,Runnable特性
                exs.submit(futureTask);
                //Future特性
                futureList.add(futureTask);
            }
            Long getResultStart = System.currentTimeMillis();
            System.out.println("结果归集开始时间="+new Date());
            //结果归集
            while(futureList.size()>0){
                Iterator<FutureTask<Integer>> iterable = futureList.iterator();
                //遍历一遍
                while(iterable.hasNext()){
                    Future<Integer> future = iterable.next();
//                    if (future.isDone()&& !future.isCancelled()) {//非阻塞
                        //Future特性
                        Integer i = future.get();//阻塞
                        System.out.println("任务i=" + i + "获取完成,移出任务队列!" + new Date());
                        list.add(i);
                        //任务完成移除任务
                        iterable.remove();
//                    }else {
//                        //避免CPU高速轮循,可以休息一下。
//                        Thread.sleep(1);
//                    }
                }
            }

            System.out.println("list="+list);
            System.out.println("总耗时="+(System.currentTimeMillis()-start)+",取结果归集耗时="+(System.currentTimeMillis()-getResultStart));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            exs.shutdown();
        }
    }

}

package com.hsj.futuretask;

import java.util.Date;
import java.util.concurrent.Callable;

/**
 * @Description 回调方法
 * @author denny
 * @author HeShengjin 2356899074@qq.com
 * @date 2018/8/17 下午3:16
 */
public class CallableTask implements Callable<Integer> {
    Integer i;

    public CallableTask(Integer i) {
        super();
        this.i = i;
    }

    @Override
    public Integer call() throws Exception {
        if (i == 1) {
            Thread.sleep(3000);//任务1耗时3秒
        } else if (i == 5) {
            Thread.sleep(5000);//任务5耗时5秒
        } else {
            Thread.sleep(1000);//其它任务耗时1秒
        }
        System.out.println("task线程:" + Thread.currentThread().getName() + "任务i=" + i + ",完成!"+ new Date());
        return i;
    }
}

三、CompletionService:

package com.hsj.completionservice;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 *
 * @ClassName: CompletionServiceDemo
 * @Description: CompletionService多线程并发任务结果归集
 * @author denny.zhang
 * @author HeShengjin 2356899074@qq.com
 * @date 2016年11月4日 下午1:50:32
 *
 */
public class CompletionServiceDemo{

    public static void main(String[] args)  {
        Long start = System.currentTimeMillis();
        //开启多线程
        ExecutorService exs = Executors.newFixedThreadPool(10);
        try {
            int taskCount = 10;
            //结果集
            List<Integer> list = new ArrayList<Integer>();
            //1.定义CompletionService
            CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(exs);
            List<Future<Integer>> futureList = new ArrayList<Future<Integer>>();
            //2.添加任务
            for(int i=0;i<taskCount;i++){
                futureList.add(completionService.submit(new Task(i+1)));
            }
            //==================结果归集===================
            //方法1:future是提交时返回的,遍历queue则按照[任务提交顺序],获取结果
            for (Future<Integer> future : futureList) {
                System.out.println("====================");
                Integer result = future.get();//线程在这里阻塞等待该任务执行完毕,按照
                System.out.println("任务result="+result+"获取到结果!"+new Date());
                list.add(result);
            }

//            //方法2.使用内部阻塞队列的take()
//            for(int i=0;i<taskCount;i++){
//                Integer result = completionService.take().get();//采用completionService.take(),内部维护阻塞队列,[任务先完成的先获取到]
//                System.out.println("任务i=="+result+"完成!"+new Date());
//                list.add(result);
//            }
            System.out.println("list="+list);
            System.out.println("总耗时="+(System.currentTimeMillis()-start));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            exs.shutdown();//关闭线程池
        }

    }

}

package com.hsj.completionservice;

import java.util.concurrent.Callable;

public class Task implements Callable<Integer> {
    Integer i;

    public Task(Integer i) {
        super();
        this.i=i;
    }

    @Override
    public Integer call() throws Exception {
        if(i==5){
            Thread.sleep(5000);
        }else{
            Thread.sleep(1000);
        }
        System.out.println("线程:"+Thread.currentThread().getName()+"任务i="+i+",执行完成!");
        return i;
    }

}

四、CompletableFuture:

package com.hsj.completablefuture;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 *
 * @ClassName:CompletableFutureDemo
 * @Description:多线程并发任务,取结果归集
 * @author diandian.zhang
 * @author HeShengjin 2356899074@qq.com
 * @date 2017年6月14日下午12:44:01
 */
public class CompletableFutureDemo {
    public static void main(String[] args) {
        Long start = System.currentTimeMillis();
        //结果集
        List<String> list = new ArrayList<String>();
        //定长10线程池
        ExecutorService exs = Executors.newFixedThreadPool(10);
        List<CompletableFuture<String>> futureList = new ArrayList<>();
        //任务
        final List<Integer> taskList = new ArrayList(){{
            add(2); add(1); add(3); add(6); add(4); add(5); add(8); add(9); add(7); add(10);
        }};
        try {

//            方式一:全流式处理转换成CompletableFuture[]+组装成一个无返回值CompletableFuture,join等待执行完毕。返回结果whenComplete获取
            CompletableFuture[] cfHaveBack = taskList
                    .stream()
                    .map(
                            object-> CompletableFuture.supplyAsync(()->calc(object), exs)
                                    .thenApply(integer->Integer.toString(integer))//中间的转换
                                    //如需获取任务完成先后顺序,此处代码即可
                                    .whenComplete((v, e) -> {
                                        System.out.println("任务"+v+"完成!result="+v+",异常 e="+e+","+new Date());
                                        list.add(v);
                                    })
                    ).toArray(CompletableFuture[]::new);
            //等待总任务完成,但是封装后无返回值,必须自己whenComplete()获取
            CompletableFuture.allOf(cfHaveBack).join();
            System.out.println("任务完成,结果list="+list+";耗时="+(System.currentTimeMillis()-start));

            //华丽丽的分割线
            System.out.println("///");

            //方式二:全流式处理转换成CompletableFuture[]+组装成一个无返回值CompletableFuture,join等待执行完毕。无返回值。
            CompletableFuture[] cfNoBack = taskList
                    .stream()
                    .map(
                            object-> CompletableFuture.runAsync(
                                    ()->calcV2(taskList,object),
                                    exs)
                    ).toArray(CompletableFuture[]::new);
            //等待总任务完成,但是封装后无返回值,必须自己whenComplete()获取
            CompletableFuture.allOf(cfNoBack).join();
            System.out.println("任务完成,结果taskList="+taskList+";耗时="+(System.currentTimeMillis()-start));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            exs.shutdown();
        }
    }

    /**
     * @Description:有返回值
     * @author HeShengjin 2356899074@qq.com
     * @date 2021/11/18 10:21
     */
    public static Integer calc(Integer i){
        try {
            if(i==1){
                //任务1耗时3秒
                Thread.sleep(3000);
            }else if(i==5){
                //任务5耗时5秒
                Thread.sleep(5000);
            }else{
                //其它任务耗时1秒
                Thread.sleep(1000);
            }
            System.out.println("task线程:"+Thread.currentThread().getName()+"任务i="+i+",完成!+"+new Date());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return i;
    }
    /**
     * @Description:没有返回值
     * @author HeShengjin 2356899074@qq.com
     * @date 2021/11/18 10:21
     */
    public static void calcV2(List<Integer> taskList,Integer i){
        try {
            if(i==1){
                //任务1耗时3秒
                Thread.sleep(3000);
            }else if(i==5){
                //任务5耗时5秒
                Thread.sleep(5000);
            }else{
                //其它任务耗时1秒
                Thread.sleep(1000);
            }
            //自己的业务逻辑
            System.out.println("task线程:"+Thread.currentThread().getName()+"任务i="+i+",完成!+"+new Date());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

感谢:多线程并发执行任务,取结果归集。终极总结:Future、FutureTask、CompletionService、CompletableFuture

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值