并发编程一CompletableFuture

线程

线程分为

  • 用户线程
  • 守护线程

用户线程:系统工作线程,他会完成这个程序需要完成的业务操作。

守护线程:是一种特殊的线程为其它线程服务的,在后台默默地完成一些系统性地服务,比如垃圾回收线程

作为一个服务线程,没有服务对象就没有必要继续运行了,如果用户线程全部结束了,意味着程序需要完成地业务操作已经结束了,系统可以退出。所以加入当系统只剩下守护线程地时候,Java虚拟机会自动退出。

CompletableFuture

Future

Feture接口(FutureTask实现类)定义了操作异步任务执行一些方法,如获取异步任务地执行结果,取消任务地执行、判断任务是否被取消、判断任务执行是否完毕等。

Future接口可以为主线程开一个分支任务,专门为主线程处理好费事和费力地复杂业务。

特点:多线程/异步/有返回值

Runnable接口不满足返回值

RunnableFuture接口不满足有返回值

FutureTask

实现RunnableFuture,构造方法中支持callable注入

缺点

get方法会阻塞线程

1、容易导致阻塞,一般加以放在程序后面,一旦调用不见不散,非要等到结果才hi离开,不管你是否计算完成,容易程序阻塞

2、假如我不愿意等待很长时间,我希望过时不侯,可以自行离开。

public class FutureTaskGet {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            System.out.println(Thread.currentThread().getName() + "\t---come in");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "task over";
        });
        Thread t1 = new Thread(futureTask, "t1");
        t1.start();
        System.out.println(futureTask.get());
        System.out.println(Thread.currentThread().getName()+"\t----end");

    }
}

completableFuture

CompletableFuture实现CompletionStage/Future接口

  • CompletionStage代表异步计算过程中地某一个阶段,一个阶段完成以后可能会出发另外一个阶段
  • 一个阶段地计算执行可以是一个Function,Consumer或者Runnable。比如:stage.thenApply(x->square(x)).thenAccept(x->System.out.print(x)).thenRun()->System.out.println())
  • 一个阶段地执行可能是被单个阶段地完成出发,也可能是由多个阶段一起触发

代表异步计算过程中的某一个阶段,一个阶段完成以后可能触发另外一个阶段,类似Linux系统地管道分隔符传参数

解决了get线程阻塞问题

当主线程停止时,CompletableFuture默认使用地线程池会立刻关闭,自己创建一个线程池

        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            int result = ThreadLocalRandom.current().nextInt(10);
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return result;
        },threadPool).whenComplete((v,e)->{
            if (e == null){
                System.out.println("--------计算完成,更新系统UpdateVa:"+v);
            }
        }).exceptionally(e->{
            e.printStackTrace();
            System.out.println("异常情况"+e.getCause()+"\t"+e.getMessage());
            return null;
        });
        System.out.println(Thread.currentThread().getName()+"线程先去忙其他任务");
        threadPool.shutdown();

join和get地区别

join不用抛异常,get需要

优点

  • 异步任务结束时,会自动回调某个对象地方法;
  • 主线程设置好回调后,不再关心异步任务地执行,异步任务之间可以顺序执行
  • 异步任务出错时,会自动回调某个对象地方法;

api

1.获得结果和触发计算

当没有运行完时,返回传入的值,

getNot(...):并不终止异步运行,返回传入参数

complete(...)终止异步运行,直接复制返回Boolean类型

2.对计算结果进行处理

计算结果串行化

thenApply:出现异常都不执行

handle:出现异常,异常地方不执行,其他地方继续执行

3.对计算结果进行消费

接受任务的处理结果,并消费无返回值

thenAccept(....)

thenRun(new Running)开启新的线程void

4.对计算速度进行选用

applyToEneither()谁快用谁

5.对计算结果进行合并

thenCombine

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值