线程池和异步

1、初始化线程的4种方式

1、实际开发中,只用线程池【高并发状态开启了n个线程,会耗尽资源】
2、当前系统中线程池只有一两个,每个异步任务提交给线程池让他自己去执行

1)、继承Thread
2)、实现 Runnable接口
3)、实现 Callable接口+FutureTask(可以拿到返回结果,可以处理异常)

 FutureTask futureTask = new FutureTask(new MyCallable());
        Thread thread = new Thread(futureTask);
        thread.start();
        //阻塞等待这个线程执行完,获取返回结果
        Integer o = (Integer) futureTask.get();

4)、线程池

区别;
1、2不能得到返回值。3可以获取返回值
1、2、3都不能控制资源
4可以控制资源,性能稳定,不会一下子所有线程一起运行

2、线程池execute和submit区别

execute:参数只能是Runnable,没有返回值
在这里插入图片描述

submit:参数可以是Runnable、Callable,返回值是FutureTask
在这里插入图片描述

3、创建线程池的方式

1、创建一个固定类型的线程池
Executors.newFixedThreadPool(10);

2、直接创建,7个参数
在这里插入图片描述

ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

corePoolSize:核心线程数,一直存在,一开始只是new 并没有start
maximumPoolSize:最大线程数量,控制资源
keepAliveTime:存活时间 【释放空闲线程(maximumPoolSize-corePoolSize) 超过存活时间释放线程】
unit:时间单位
workQueue: 阻塞队列,只要有线程空闲,就会去队列取出新的任务执行
threadFactory:线程的创建工厂【可以自定义】
RejectedExecutionHandler handler:拒绝策略

3、顺序:
1、先创建核心线程运行任务
2、核心线程满了,放入阻塞队列,空闲的core会自己去阻塞队列获取
new LinkedBlockingDeque()默认是Integer的最大值,
3、阻塞队列满了继续创建线程,最多创建maximumPoolSize个
4、如果传入了拒绝策略会执行,否则抛出异常
5、拒绝策略:
1、丢弃最老的 Rejected
2、调用者同步调用,直接调用run方法,不创建线程了 Caller
3、直接丢弃新任务 Abort 【默认使用这个】
4、丢弃新任务,并且抛出异常 Discard
在这里插入图片描述

4、常见的4种线程池

1、CachedThreadPool:核心线程数是0,如果空闲会回收所有线程【缓存线程池】
2、FixedThreadPool:核心线程数 = 最大线程数,【不回收】
3、ScheduledThreadPool:定时任务线程池,多久之后执行【可提交核心线程数,最大线程数是Integer.Max】
4、SingleThreadPool:核心与最大都只有一个【不回收】,后台从队列中获取任务

5、使用线程池的好处

1、降低资源的消耗【减少创建销毁线程的开销】
通过重复利用已经创建好的线程降低线程的创建和销毁带来的损耗

2、提高响应速度【控制线程个数】
因为线程池中的线程数没有超过线程池的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程就能执行

3、提高线程的可管理性【例如系统中可以创建两个线程池,核心线程池、非核心线程池【短信等】,关闭非核心线程池释放内存资源】
线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销。无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使用线程池进行统一分配

6、CompletableFuture异步编排

6.1、创建异步对象提交任务runAsync、supplyAsync

CompletableFuture提供了四个静态方法来创建一个异步操作。

1public static Completab1eFuture<Void> runAsync(Runnable runnable)
2public static completableFuturecVoid> runAsync(Runnable runnable,Executor executor)
3public static <U> CompletableFuture<U> supplyAsync(Supplier<U>supplier)
4public static <U> CompletableFuturecU> supplyAsync(Supplier<U> supplier,Executor
executor)

1、runXXX没有返回结果,supplyXxx有返回结果
2、可以传入自定义线程池,否则使用默认线程池

public class ThreadTest {
    public static ExecutorService excutor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(()->{
            System.out.println("线程池执行任务1 : 1+1");
            return 1 + 1;
        },service);
        System.out.println("main end.... result: " + future.get());

    }
}

6.2、whencomplete接收任务返回值

public completableFuture<T> whencomplete(BiConsumer<? super T,? super Throwable> action);
public CompletableFuture<T>whenCompleteAsync(BiConsumer <? super T,? super Throwable>
action);
public completableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable>
action,Executor executor);
public completableFuture<T>exceptionally(Function<Throwable,? extends T> fn);

whenComplete可以处理正常和异常的计算结果,exceptionally处理异常情况。
whenComplete和whenCompleteAsync的区别:
whenComplete:是执行当前任务的线程执行继续执行whenComplete的任务。
whenCompleteAsync:是执行把 whenCompleteAsync这个任务继续提交给线程池来进行执行。

方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)

public static ExecutorService service = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");
        CompletableFuture<Integer> future = CompletableFuture
                .supplyAsync(()->{
                    System.out.println("线程池执行任务1 : 10 / 0");
                    return 10 / 0;
                }, service)
                .whenComplete((result, exception)-> {
                    // 得到异常信息,但是不能修改返回的数据
                    System.out.println("获取任务1的结果:" + result);
                    System.out.println("获取任务1的异常:" + exception);
                })
                .exceptionally((exception)-> {
                    System.out.println("获取任务1的异常,并提供一个默认返回值" + exception);
                    return 100;
                });
        System.out.println("main end.... result: " + future.get());
        }

6.3、handle方法【对返回值进行加工,再返回】

public <U> completionStage<U> handle(BiFunction<? super TThrowable? extends U> fn);
public <U> completionStage<U>handleAsync(BiFunction<? super TThrowable? extends U>
fn);
public > CompletionStage<U> handleAsync(BiFunction<? super TThrowable? extends U>
fn,Executor executor ) ;
和complete一样,可对结果做最后的处理(可处理异常),可改变返回值。

 public static ExecutorService service = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(()->{
//            System.out.println("线程池执行任务1 : 1+1");
//            return 1 + 1;
//        },service);
        CompletableFuture<Integer> future = CompletableFuture
                .supplyAsync(()->{
                    System.out.println("线程池执行任务1 : 10 / 0");
                    return 10 / 0;
                }, service)
                .whenComplete((result, exception)-> {
                    // 得到异常信息,但是不能修改返回的数据
                    System.out.println("获取任务1的结果:" + result);
                    System.out.println("获取任务1的异常:" + exception);
                })
                .exceptionally((exception)-> {
                    System.out.println("获取任务1的异常,并提供一个默认返回值" + exception);
                    return 100;
                })
                .handle((result,exception)->{
                    System.out.println("获取任务1的结果:" + result);
                    // 可对结果做最后的处理(可处理异常),可改变返回值
                    if (exception != null) {
                        System.out.println("获取任务1的异常:" + exception);
                    }
                    System.out.println("异常不会传播,前面调用exceptionally方法处理了异常");
                    return result == null ? 0 : result*2;
                });
        System.out.println("main end.... result: " + future.get());

    }

6.4、线程串行化方法【then】

thenRun:继续执行,不接受上一个任务的返回结果
thenAccept:继续执行,接受上一个任务的返回结果
thenApply:继续执行,感知上一任务的返回结果,并且自己的返回结果也被下一个任务所感知

public <U> CompletableFuturecU> thenApply(Function<? super T,? extends U> fn)
public <U> Completab1eFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn,
Executor executor)
public completionstage<Void> thenAccept(Consumer<? super T> action);
public completionStage<Void> thenAcceptAsync(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,Executor
executor);
public Completionstage<Void> thenRun(Runnable action);
public Completionstage<Void> thenRunAsync(Runnable action);
public completionStage<Void> thenRunAsync(Runnable action,Executor executor);

    public static ExecutorService service = Executors.newFixedThreadPool(10);

public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(()->{
//            System.out.println("线程池执行任务1 : 1+1");
//            return 1 + 1;
//        },service);
        CompletableFuture<Integer> future = CompletableFuture
                .supplyAsync(()->{
                    System.out.println("线程池执行任务1 : 10 / 0");
                    return 10 / 0;
                }, service)
                .whenComplete((result, exception)-> {
                    // 得到异常信息,但是不能修改返回的数据
                    System.out.println("获取任务1的结果:" + result);
                    System.out.println("获取任务1的异常:" + exception);
                })
                .exceptionally((exception)-> {
                    System.out.println("获取任务1的异常,并提供一个默认返回值" + exception);
                    return 100;
                })
                .handle((result,exception)->{
                    System.out.println("获取任务1的结果:" + result);
                    // 可对结果做最后的处理(可处理异常),可改变返回值
                    if (exception != null) {
                        System.out.println("获取任务1的异常:" + exception);
                    }
                    System.out.println("异常不会传播,前面调用exceptionally方法处理了异常");
                    return result == null ? 0 : result*2;
                })
                .thenApplyAsync(result -> result*2);
        System.out.println("main end.... result: " + future.get());

    }

6.5、两任务组合–-都要完成

public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);


public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);


public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);

两个任务必须都完成,触发该任务。
thenCombine:组合两个future,获取两个future的返回结果,并返回当前任务的返回值
thenAcceptBoth:组合两个future,获取两个future任务的返回结果,然后处理任务,没有
返回值。
runAfterBoth:组合两个future,不需要获取future的结果,只需两个future处理完任务后,
处理该任务。

public static ExecutorService excutor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务1 start..");
            System.out.println("任务1 end..");
            return 1+1;
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务2 start..");
            System.out.println("任务2 end..");
            return "hello";
        });

        CompletableFuture<String> future3 = future1.thenCombineAsync(future2, (result1, result2) -> {
            return "任务3 :组合前两个任务的返回值返回 --" + result1 + "---" + result2;
        }, excutor);
        System.out.println("main end.... 返回值:" + future3.get());
    }

6.6、两任务组合-一个完成

1、applyToEither:Function 带参有返回值【能获取前面任务的结果,自己有返回结果】【成功的那个任务的结果】
2、acceptEither:Consumer 带参无返回值【能获取前面任务的结果,自己没有返回结果】
3、runAfterEither:Runnable 无参无返回值【不能获取前面任务的结果,自己也没有返回结果】
	supplyAsync:Supplier:无参有返回值【不能获取前面任务的结果,自己有返回值】
public <U> CompletableFuture<U> applyToEither(
    CompletionStage<? extends T> other, Function<? super T, U> fn) {
    return orApplyStage(null, other, fn);
}

public <U> CompletableFuture<U> applyToEitherAsync(
    CompletionStage<? extends T> other, Function<? super T, U> fn) {
    return orApplyStage(asyncPool, other, fn);
}

public <U> CompletableFuture<U> applyToEitherAsync(
    CompletionStage<? extends T> other, Function<? super T, U> fn,
    Executor executor) {
    return orApplyStage(screenExecutor(executor), other, fn);
}

public CompletableFuture<Void> acceptEither(
    CompletionStage<? extends T> other, Consumer<? super T> action) {
    return orAcceptStage(null, other, action);
}

public CompletableFuture<Void> acceptEitherAsync(
    CompletionStage<? extends T> other, Consumer<? super T> action) {
    return orAcceptStage(asyncPool, other, action);
}

public CompletableFuture<Void> acceptEitherAsync(
    CompletionStage<? extends T> other, Consumer<? super T> action,
    Executor executor) {
    return orAcceptStage(screenExecutor(executor), other, action);
}

public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,
                                              Runnable action) {
    return orRunStage(null, other, action);
}

public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
                                                   Runnable action) {
    return orRunStage(asyncPool, other, action);
}

public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
                                                   Runnable action,
                                                   Executor executor) {
    return orRunStage(screenExecutor(executor), other, action);
}
public static ExecutorService excutor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start ....");

        CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务1 start..");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务1 end..");
            return 1+1;
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()->{
            System.out.println("任务2 start..");
            System.out.println("任务2 end..");
            return "hello";
        });

        // 两个任务都完成才执行任务3
//        CompletableFuture<String> future3 = future1.thenCombineAsync(future2, (result1, result2) -> {
//            return "任务3 :组合前两个任务的返回值返回 --" + result1 + "---" + result2;
//        }, excutor);

        // 任一任务完成就可以执行任务3【返回值是future1的泛型】
        CompletableFuture<String> future3 = future1.applyToEitherAsync(future2, (result) -> {
            return "任务3 :组合先执行完的任务的结果 --" + result;
        }, excutor);
        System.out.println("main end.... 返回值:" + future3.get());
    }

6.7、多任务组合【总结】

// 1、等待所有任务完成
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
    return andTree(cfs, 0, cfs.length - 1);
}
//2、只有一个任务完成
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
    return orTree(cfs, 0, cfs.length - 1);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值