JUC__Future与CompletableFuture

一、为什么多线程很重要?

  1. 硬件方面:摩尔定律的失效,多核的出现
  2. 软件方面:高并发系统

摩尔定律是由英特尔(Intel)创始人之一戈登·摩尔(Gordon Moore)提出来的。其内容为:当价格不变时,集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍。换言之,每一美元所能买到的电脑性能,将每隔18个月翻两倍以上。这一定律揭示了信息技术进步的速度。

二、进程、线程、管程

进程:资源分配的基本单位
线程:cpu调度的基本单位
管程:Monitor(锁)
在这里插入图片描述

三、用户线程和守护线程

1.thread.setDaemon()设置守护线程
2.用户线程结束,守护线程自动结束

public class YonghuAndShouhu {
    public static void main(String[] args) {
        Thread A =new Thread(()->{
            System.out.println("这是守护线程");
            while (true){//保证这个方法不停
            }
        },"A");
        A.setDaemon(true);
        A.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("这是main线程");

    }
}

四、FutureTask的get()方法引起阻塞的解决办法

在这里插入图片描述
FutureTask实现了RunnableFuture,RunnableFuture继承了Future和Runnable接口

使用FutureTask的get()方法时可能会引起阻塞(本程序两秒后才返回值)

public class FutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> vFutureTask = new FutureTask<>(() -> {
            Thread.sleep(2000);
            return 1024;
        });

        new Thread(vFutureTask,"a").start();
        System.out.println(vFutureTask.get());//get()会引起阻塞

        System.out.println("main");


    }
}

解决get()方法阻塞的方法有那些?
get得到的是返回值,这个返回值要在其他方法里用到
① futureTask 返回值出来被调用后才出main(出现阻塞)
② CompletableFuture 在等返回值时mian已经出来,等返回值出来再被调用

  1. 将get()方法放到最后 (不见不散)
  2. 用有参get()方法:.get(1, TimeUnit.SECONDS) (过时不候)
  3. 轮询 :
public class FutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        FutureTask<Integer> vFutureTask = new FutureTask<>(() -> {
            Thread.sleep(2000);
            return 1024;
        });

        new Thread(vFutureTask,"a").start();
//

        //轮询
        while(true){
            if (vFutureTask.isDone()){
                System.out.println(vFutureTask.get());
                break;
            }else{
                System.out.println("不要催l");
            }
        }

        System.out.println("main");


    }
}

在这里插入图片描述
4. CompletableFuture

五、CompletableFuture(对Future的加强)

在这里插入图片描述

1.四个静态方法的使用

public class CompletableFutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,20,1L, TimeUnit.SECONDS,new LinkedBlockingDeque<>(50), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        //无返回值  默认线程池
        CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "1");
        });
        System.out.println(voidCompletableFuture1.get());
        //无返回值   自定义线程池
        CompletableFuture<Void> voidCompletableFuture2 = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "2");
        },threadPoolExecutor);
        System.out.println(voidCompletableFuture2.get());

        //有返回值   默认线程池
        CompletableFuture<Object> objectCompletableFuture3 = new CompletableFuture<>().supplyAsync(()->{
            System.out.println(Thread.currentThread().getName() + "3");
            return 3;
        });
        System.out.println(objectCompletableFuture3.get());

        //有返回值  自定义线程池
        CompletableFuture<Object> objectCompletableFuture4 = new CompletableFuture<>().supplyAsync(()->{
            System.out.println(Thread.currentThread().getName() + "4");
            return 4;
        },threadPoolExecutor);
        System.out.println(objectCompletableFuture4.get());

        threadPoolExecutor.shutdown();

 

在这里插入图片描述
解决阻塞



public class CompletableFutureTest2 {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(()->{
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        }).thenApply((f)->{
            return f+1;
        }).whenComplete((v,e)->{
            if (e == null){
                System.out.println("result"+v);
            }
        }).exceptionally((e)->{
            e.printStackTrace();
            return null;
        });
        
        System.out.println("main");
       //如果主线程关闭,那么默认的线程池会关闭,让主线程多跑5秒,让上面的result跑出来
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

在这里插入图片描述

2.常用方法

  1. 得出处理结果
    在这里插入图片描述

  2. 对计算结果进行处理
    在这里插入图片描述

  3. 对计算结果进行消费

在这里插入图片描述
4. 对计算速度进行选用
applyToEither()
假设玩家A玩家B玩游戏,谁先出来谁赢

public class applyToEitherTest {
    public static void main(String[] args) {
        System.out.println(CompletableFuture.supplyAsync(() -> {
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            try {
                Thread.currentThread().sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 2;
        }), r -> {
            return r;
        }).join());
    }

}
  1. 对计算结果进行合并
    thenCombine()
public class applyToEitherTest {
    public static void main(String[] args) {
        System.out.println(CompletableFuture.supplyAsync(() -> {

            return 1;
        }).thenCombine(CompletableFuture.supplyAsync(() -> {
 
            return 2;
        }), (r1,r2) -> {
            return r1+r2;
        }).join());
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值