初始化线程的方式:
1、继承Thread类
Thread01 thread01 = new Thread01();
thread01.start();
2、实现Runnable接口
Thread02 thread02 = new Thread02();
new Thread(thread02).start();
3、实现Callable接口+FutureTask(可以拿到返回结果,处理异常)
FutureTask<Object> task = new FutureTask<>(new Thread03());
new Thread(task).start();
// 阻塞等待整个线程执行完成,获取返回结果
Object obj = task.get();
4、线程池
常见的四种线程池
1、Executors.newCachedThreadPool(); core是0,所有线程都可以回收
2、Executors.newFixedThreadPool(); 固定大小,core=max,所有线程都不可回收
3、Executors.newScheduledThreadPool(); 定时任务的线程池
4、Executors.newSingleThreadExecutor(); 单线程的线程池,后台从队列里面获取任务,挨个执行
new ThreadPoolExecutor();
参数:
int corePoolSize:核心线程数(一直存在,除非allowCoreThreadTimeOut)
int maximumPoolSize:最大线程数,控制资源
long keepAliveTime:存活时间:只要线程空闲时间大于keepAliveTime,释放空闲的线程(maximumPoolSize-corePoolSize)
TimeUnit unit:存活时间单位
BlockingQueue<Runnable> workQueue:阻塞队列,多余的任务存放在队列中,当有空闲的线程时,就会去队列中取出新的线程执行
ThreadFactory threadFactory:线程的创建工厂
RejectedExecutionHandler handler:如果队列满了,就会按照指定的拒绝策略拒绝执行任务
工作顺序:
1、线程池创建,准备好core数量的核心线程,等待执行任务
2、新的任务进来,用core准备好的线程执行
1)、core满了,就将再进来的线程放到阻塞队列中,空闲的core就会自动去阻塞队列中获取任务执行
2)、阻塞队列满了,就会开启新的线程,最多开到maximumPoolSize
3)、如果线程数开到了max的大小,还有新的任务进来,就会使用reject的拒绝策略进行处理
4)、max都执行好了,max-core数量的空闲线程就会在keepAliveTime指定的时间后销毁,最终保持到core的大小
3、所有的线程创建都是由threadFactory创建的
四种创建方式的区别:
1、2不能得到返回值,3可以得到返回值
1、2、3都不能控制资源
4可以控制资源,性能稳定
为什么使用线程池:
-
降低资源消耗(通过重复利用已经创建好的线程降低线程的创建和销毁所带来的消耗)
-
提高响应速度(因为线程池的线程数没有超过线程的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程即可执行)
-
提高线程的可管理性(线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销。无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使用线程池进行统一分配)
CompletableFuture:异步编排
1、创建异步对象
// 没有返回值
CompletableFuture<Void> runAsync(Runnable runnable);
CompletableFuture<Void> runAsync(Runnable runnable,Executor executor);
// 有返回值
CompletableFuture<U> supplyAsync(Supplier<U> supplier);
CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor);
- runXxx都是没有返回结果的,supplyXxx都是可以获取返回结果的
- 可以传入自定义的线程池,否则就用默认的线程池;
2、计算完成时回调方法
// 方法完成后的感知
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处理异常情况。
- whenCompleteAsync:是执行把 whenCompleteAsync这个任务继续提交给线程池来进行执行。
- whenComplete:是执行当前任务的线程继续执行whenComplete的任务。
- 方法不以Async结尾意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)
3、handle方法
// 方法完成后的处理
CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);
CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);
CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);
和complete一样,可对结果做最后的处理(可处理异常),可改变返回值。
4、线程串行化方法
CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn);
CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor);
CompletableFuture<Void> thenAccept(Consumer<? super T> action);
CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action);
CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor);
CompletableFuture<Void> thenRun(Runnable action);
CompletableFuture<Void> thenRunAsync(Runnable action);
CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor);
- thenApply方法:既能接收上一步返回结果,又有返回值
- thenAccept方法:能接收上一步的返回结果,但是无返回值
- thenRun方法:不能获取到上一步的执行结果,无返回值
- 带有Async默认是异步执行的。同之前。以上都要前置任务成功完成
5、两任务组合–都要完成
CompletableFuture<V> thenCombine(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn);
CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn);
CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn, Executor executor);
CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action);
CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action);
CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action, Executor executor);
runAfterBoth(CompletionStage<?> other,Runnable action);
CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,Runnable action);
CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,Runnable action,Executor executor);
- 两个任务必须都完成,触发该任务
- thenCombine:组合两个 future,获取两个future的返回结果,并返回当前任务的返回值
- thenAcceptBoth:组合两个future,获取两个future任务的返回结果,然后处理任务,没有返回值。
- runAfterBoth:组合两个 future,不需要获取future的结果,只需两个future处理完任务后,处理该任务。
6、两任务组合–一个完成
CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn);
CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn,Executor executor);
CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action);
CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action);
CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action,Executor executor);
CompletableFuture<Void> runAfterEither(CompletionStage<?> other,Runnable action);
CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action);
CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action,Executor executor);
- 当两个任务中任意一个future任务完成的时候,执行任务。
- applyToEither:两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。
- acceptEither:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值。
- runAfterEither:两个任务有一个执行完成,不需要获取future的结果,处理任务,也没有返回值。
7、多任务组合
CompletableFuture<Void> allOf(CompletableFuture<?>... cfs);
CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs);
- allOf:等待所有任务完成
- anyof:只要有一个任务完成