初始化线程的4种方式:
1.继承Thread
Thread01 thread01 = new Thread01(); new Thread(thread01).start();
2.实现Runnable接口
Runnable01 runnable01 = new Runnable01(); new Thread(runnable01).start();
3.实现Callable接口 + FutureTask(可以拿到返回值结果,可以处理异常)
FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable01()); new Thread(futureTask).start(); // 阻塞等待整个线程执行完成,获取返回结果 Integer integer = futureTask.get();
4.线程池
/** ThreadPoolExecutor 七大参数 int corePoolSize:[5] 核心线程数[一直存在除非(allowCoreThreadTimeOut)];线程池,创建好以后就准备就虚的线程数量,就等待来接受异步任务去执行 5个 Thread thread = new Thread(); thread.start(); int maximumPoolSize:[200] 最大线程数量;控制资源 long keepAliveTime:存活时间。如果当前的线程数量大于core数量。 释放空闲的线程(maximumPoolSize-corePoolSize)。只要线程空闲大于指定的keepAliveTime; TimeUnit unit:时间单位 BlockingQueue<Runnable> workQueue:阻塞队列。如果任务有很多,就会将目前多的任务放在队列里面。 只要有线程空闲,就会去队列里面取出新的任务继续执行。 ThreadFactory threadFactory:线程的创建工厂。 RejectedExecutionHandler handler:如果队列满了,按照指定的拒绝策略拒绝执行任务 */
工作顺序:
-
线程池创建,准备好core数量的核心线程,准备接受任务
-
core满了,就准备再进来的任务放入阻塞队列中。空闲的core就会自己去阻塞队列获取任务执行
-
阻塞队列满了,就直接开新线程执行,最大只能开到max指定的数量
-
max满了就用
RejectedExecutionHandler
拒绝任务 -
max都执行完成,有很多空闲,在指定的时间
keepAliveTime
以后,释放max-core这些线程
new LinkedBlockingDeque<>()
: 默认最大队列数是Integer的最大值。可能会内存不够,所以要指定最大队列数 -
面试题
一个线程池 core 7; max 20 , queue: 50 , 100并发进来如何分配 7个会立即执行,50个会进入队列,再开13个进行执行。剩下的30个就使用拒绝策略。 如果不想抛弃还要执行线程。可使用 .CallerRunsPolicy() 拒绝策略
常见的4种线程池
Executors.newCachedThreadPool()
core是0,所有都可回收 Executors.newFixedThreadPool()
固定大小,core=max ;都不可回收 Executors.newScheduledThreadPool()
定时任务的线程池 Executors.newSingleThreadExecutor()
单线程的线程池,后台从队列里面获取任务,挨个执行
CompletableFuture异步编排介绍
1.创建异步对象
CompletableFuture提供了四个静态方法来创建一个异步操作
public static CompletableFuture<Void> runAsync(Runnable runnable) { return asyncRunStage(asyncPool, runnable); } public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) { return asyncRunStage(screenExecutor(executor), runnable); } public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) { return asyncSupplyStage(asyncPool, supplier); } public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) { return asyncSupplyStage(screenExecutor(executor), supplier); }
-
runXxxx都是没有返回结果的,suppleXxx都是可以获取返回结果的
-
可以传入自定义的线程池,否则就用默认的线程池。
2.计算完成时回调方法
public CompletableFuture<T> whenComplete( BiConsumer<? super T, ? super Throwable> action) { return uniWhenCompleteStage(null, action); } public CompletableFuture<T> whenCompleteAsync( BiConsumer<? super T, ? super Throwable> action) { return uniWhenCompleteStage(asyncPool, action); } public CompletableFuture<T> whenCompleteAsync( BiConsumer<? super T, ? super Throwable> action, Executor executor) { return uniWhenCompleteStage(screenExecutor(executor), action); } public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn) { return uniExceptionallyStage(fn); }
whenComplete可以处理正常和异步的计算结果,exceptionally处理异常情况。
whenComplete和whenCompleteAsync的区别:
whenComplete:是执行当前任务的线程执行继续执行whenComplete的任务。
whenCompleteAsync:是执行把whenCompleteAsync这个任务继续提交给线程池来进行执行。
方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同线程池,也可能会被同一个线程选中执行)
3.handle方法
public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn) { return uniHandleStage(null, fn); } public <U> CompletableFuture<U> handleAsync( BiFunction<? super T, Throwable, ? extends U> fn) { return uniHandleStage(asyncPool, fn); } public <U> CompletableFuture<U> handleAsync( BiFunction<? super T, Throwable, ? extends U> fn, Executor executor) { return uniHandleStage(screenExecutor(executor), fn); }
和complete一样,可对结果做最后的处理(可处理异常),可改变返回值。
4.线程串行化方法
public <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn) { return uniApplyStage(null, fn); } public <U> CompletableFuture<U> thenApplyAsync( Function<? super T,? extends U> fn) { return uniApplyStage(asyncPool, fn); } public <U> CompletableFuture<U> thenApplyAsync( Function<? super T,? extends U> fn, Executor executor) { return uniApplyStage(screenExecutor(executor), fn); } public CompletableFuture<Void> thenAccept(Consumer<? super T> action) { return uniAcceptStage(null, action); } public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) { return uniAcceptStage(asyncPool, action); } public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor) { return uniAcceptStage(screenExecutor(executor), action); } public CompletableFuture<Void> thenRun(Runnable action) { return uniRunStage(null, action); } public CompletableFuture<Void> thenRunAsync(Runnable action) { return uniRunStage(asyncPool, action); } public CompletableFuture<Void> thenRunAsync(Runnable action, Executor executor) { return uniRunStage(screenExecutor(executor), action); }
thenApply
方法,当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值。
thenAccept
方法,消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
thenRun
方法,只要上面的任务执行完成,就开始执行thenRun
,只要处理完任务后,执行thenRun
的后续操作
带Async默认是异步执行的,同之前。
以上都要前置任务成功完成。
Function<? super T,? extends U>
T: 上一个任务返回结果的类型
U: 上一个任务返回异常的类型
5.两任务组合 - 都要完成
public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn) { return biApplyStage(null, other, fn); } public <U,V> CompletableFuture<V> thenCombineAsync( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn) { return biApplyStage(asyncPool, other, fn); } public <U,V> CompletableFuture<V> thenCombineAsync( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor) { return biApplyStage(screenExecutor(executor), other, fn); } public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action) { return biAcceptStage(null, other, action); } public <U> CompletableFuture<Void> thenAcceptBothAsync( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action) { return biAcceptStage(asyncPool, other, action); } public <U> CompletableFuture<Void> thenAcceptBothAsync( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor) { return biAcceptStage(screenExecutor(executor), other, action); } public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action) { return biRunStage(null, other, action); } public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action) { return biRunStage(asyncPool, other, action); } public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor) { return biRunStage(screenExecutor(executor), other, action); }
两个任务必须都完成,触发该类任务。
thenCombine
:组合两个future,获取两个future的返回结果,并返回当前任务的返回值
thenAcceptBoth
:组合两个future,获取两个future任务的返回结果,然后处理任务,没有返回值。
runAfterBoth
:组合两个future,不需要future的结果,只需两个future处理完任务后,处理该任务。
6.两任务组合 - 一个完成
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); }
当两个任务中,任意一个future任务完成的时候,执行任务。
applyToEither
:两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。
acceptEither
:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值。
runAfterEither
:两个任务有一个执行完成,不需要获取future的结果,处理任务,也没有返回值。
7.多任务组合
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) { return andTree(cfs, 0, cfs.length - 1); } public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) { return orTree(cfs, 0, cfs.length - 1); }
allOf:等待所有任务完成
anyOf:只要有一个任务完成