参考链接
P193-202
https://www.bilibili.com/video/BV1np4y1C7Yf?p=193&spm_id_from=pageDriver
package com.xunqi.gulimall.search.thread;
import java.util.concurrent.*;
/**
* @Description:
* @Created: with IntelliJ IDEA.
* @author: cyb
* @createTime: 2021-08-19 11:16
**/
public class ThreadTest {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
/**
* 1)、继承Thread
* Thread01 thread = new Thread01();
* thread.start();//启动线程
*
* 2)、实现Runnable接口
* Runnable01 runnable01 = new Runnable01();
* new Thread( runnable01).start();
*
* 3)、实现Callable接口 + FutureTask (可以拿到返回结果,可以处理异常)
* FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
* new Thread(futureTask).start();
* //阳塞等待整个线程执行完成,获取返回结果
* Integer integer =futureTask.get();
*
* 4) 线程池[ExecutorService]
* 给线程池直接提交任务。
* service.execute(new Runnable01());
* 1.创建。
* 1)、Executors
* 2)。new ThreadPoolExecutor
* Future可以获取到异步结果
*
* 区别;
* 1.2不能得到返回值。3可以获取返回值
* 1、2. 3都不能控制资源
* 4可以控制资源,性能稳定。
*
*
*
*
*/
// System.out.println("main......start.....");
// Thread thread = new Thread01();
// thread.start();
// System.out.println("main......end.....");
// Runnable01 runnable01 = new Runnable01();
// new Thread(runnable01).start();
// FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
// new Thread(futureTask).start();
// System.out.println(futureTask.get());
/**
* 控制资源避免资源浪费,性能稳定,实际开发只用线程池
*
*/
// service.execute(new Runable01());
// Future<Integer> submit = service.submit(new Callable01());
// submit.get();
System.out.println("main......start.....");
// CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
// System.out.println("当前线程:" + Thread.currentThread().getId());
// int i = 10 / 2;
// System.out.println("运行结果:" + i);
// }, executor);
/**
* 方法完成后的处理
*/
// CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
// System.out.println("当前线程:" + Thread.currentThread().getId());
// int i = 10 / 0;
// System.out.println("运行结果:" + i);
// return i;
// }, executor).whenComplete((res,exception) -> {
// //虽然能得到异常信息,但是没法修改返回数据
// System.out.println("异步任务成功完成了...结果是:" + res + "异常是:" + exception);
// }).exceptionally(throwable -> {
// //可以感知异常,同时返回默认值
// return 10;
// });
/**
* 方法执行完后端处理
*/
// CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
// System.out.println("当前线程:" + Thread.currentThread().getId());
// int i = 10 / 2;
// System.out.println("运行结果:" + i);
// return i;
// }, executor).handle((result,thr) -> {
// if (result != null) {
// return result * 2;
// }
// if (thr != null) {
// System.out.println("异步任务成功完成了...结果是:" + result + "异常是:" + thr);
// return 0;
// }
// return 0;
// });
/**
* 线程串行化
* 1、thenRunL:不能获取上一步的执行结果
* 2、thenAcceptAsync:能接受上一步结果,但是无返回值
* 3、thenApplyAsync:能接受上一步结果,有返回值
*
*/
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, executor).thenApplyAsync(res -> {
System.out.println("任务2启动了..." + res);
return "Hello" + res;
}, executor);
System.out.println("main......end....." + future.get());
}
/**
* 两任务组合
*
* 两个任务执行完后执行第三个任务
* future01.runAcceptBothAsync(future02),()->{
* ……
* },executor);
*
* 两个任务执行完后带返回值,执行第三个任务
* future01.thenAcceptBothAsync(future02),(f1,f2)->{
* ……
* },executor);
*
* 两个任务合并完后带返回值,执行第三个任务
* CompletableFuture<String> future = future01.thenCombineAsync(future02),(f1,f2)->{
* ……
* return ;
* },executor);
*
* future.get();
*
*/
/**
* 两个任务一个完成,就执行任务3
future01.runAfterEitherAsync(future02),()->{
任务3
* ……
* },executor);
*
*
* 两个任务一个完成,带返回结果执行任务3
future01.acceptEitherAsync(future02),(res)->{
任务3
* ……
* },executor);
*
*
* 两个任务一个完成,带返回结果 执行任务3 返回结果
CompletableFuture<String> future =future01.applyToEitherAsync(future02),(res)->{
任务3
* ……
* return ;
* },executor);
*/
/**
* 多任务组合
*
*
*
*CompletableFuture<String> future01 = CompletableFuture.supplyAsync(() -> {
* ……
* return ;
* }, executor);
*
* CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
* ……
* return ;
* }, executor);
*
*
* CompletableFuture<String> future03 = CompletableFuture.supplyAsync(() -> {
* ……
* return ;
* }, executor);
*
* CompletableFuture<void> allOf = CompletableFuture.allOff(future01,future02,future03);
* allOf.get();//阻塞等待全部任务完成
* future01.get();future02.get();future03.get();
*
* 只要有一个任务完成就执行
* CompletableFuture<void> anyOf = CompletableFuture.anyOff(future01,future02,future03);
* anyOf.get();//只返回一个
*
*/
private static void threadPool() {
/**
* 七大参数
* int corePoolSize, 核心线程数
* int maximumPoolSize, 最大线程数量
* long keepAliveTime, 存活时间 释放 空闲线程(maximumPoolSize-corePoolSize的线程),只要线程空闲大于指定的keepAliveTime
* TimeUnit unit, 时间单位
* BlockingQueue<Runnable> workQueue, 阻塞队列 将多余的线程放在阻塞队列中当有空闲线程时释放阻塞去执行
* ThreadFactory threadFactory, 线程创建工厂
* RejectedExecutionHandler handler 拒绝策略 如果队列满了,按照我们指定的拒绝策略
*
* 工作顺序
*
* 1)、线程池创建,准备好core数量的核心线程,准备接受任务
* 1.1. core满了,就将再进来的任务放入阻塞队列中。空闲的core就会自己去阻塞队列获取任务执行
* 1.2.阻塞队列满了。就直接开新线程执行,最大只能开到max指定的数量
* 1.3、max满了就用RejectedExecut ionHandler拒绝任务
* 1.4、max都执行完成。有很多空闲.在指定的时间heepAliveTime以后,释放max-core这些线程new LinkedBlockingQeque<>().默认是Integer的最大值。
*
* 一个线程池core.7 max.20,queue:50, 100并发进来怎么分配的:
* 7个会立即得到执行,50个会进入队列,再开13个进行执行。剩下的30个就使用拒绝策略。
* 如果不想抛弃还要执行。CallerRunsPolicys
*
*/
ExecutorService threadPool = new ThreadPoolExecutor(
200,
10,
10L,
TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(10000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
//定时任务的线程池
ExecutorService service = Executors.newScheduledThreadPool(2);
// Executors.newCachedThreadPool(); core是0 多有都可以回收
// Executors.newFixedThreadPool(); 固定大小 core=max 都不可以回收
// Executors.newSingleThreadExecutor(); 单线程的线程池,从队列获取任务,挨个执行
}
public static class Thread01 extends Thread {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
}
}
public static class Runable01 implements Runnable {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
}
}
public static class Callable01 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}
}
}