参考链接https://blog.csdn.net/pyd1040201698/article/details/108430376
异步和线程的关系
异步的意思就是有多个线程去执行多个任务,所以叫异步。
线程的创建方式有四种,我们要用线程池的方式创建线程。
异步编排:就是一个任务需要4个步骤,每一个步骤使用一个线程进行同步执行,提高了任务完成的速度。
线程池详解,异步运行
线程池的创建方式
- 使用线程池工具类Executors创建
public static ExecutorService service = Executors.newFixedThreadPool(10);
- 直接new线程池对象进行创建。理解7大参数
ExecutorService threadPool = new ThreadPoolExecutor(
200,
10,
10L,
TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(10000),//队列
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
//初始化线程,并提交给线程池进行执行
threadPool.execute(new Runable01());
线程池的七大参数
工作顺序
4中常见的线程池
Executors.newCachedThreadPool(); coer是0,所有又可以回收
Executors.newFixedThreadPool(); 固定大小,core=max; 都不可回收
Executors.newScheduledThreadPool(); 定时任务的线程池
Executors.newSingleThreadExecutor(); 单线程的线程池,后台从队列里面获取任务,挨个执行
使用线程池的好处
异步编排
CompletableFuture 讲解 195-201
https://blog.csdn.net/pyd1040201698/article/list/3
解决上面的问题,可以使用异步编排。
代码实现
public class ThreadTest {
/**
* 初始化线程的4种方式:
*
* 继承Thread
* 实现Runnable接口
* 实现Callable接口 + FutureTask (可以拿到返回结果,可以处理异常)
* 线程池
* 方式1和方式2:主进程无法获取线程的运算结果。不适合当前场景
*
* 方式3:主进程可以获取线程的运算结果,并设置给itemVO,但是不利于控制服务器中的线程资源。可以导致服务器资源耗尽。
*
* 方式4:通过如下两种方式初始化线程池:可以控制资源
*/
//创建自己的线程池,线程池应该系统只有一个
public static ExecutorService service = Executors.newFixedThreadPool(10);
public void threadDemo() throws ExecutionException, InterruptedException{
//======================================================1.继承Thread
// System.out.println("main......start.....");
// Thread thread = new Thread01();
// thread.start(); //启动线程
// System.out.println("main......end.....");
//======================================================2 实现Runnable接口
// System.out.println("main......start.....");
// Runable01 runable01 = new Runable01();
// new Thread(runable01).start();
//======================================================3 实现Callable接口 + FutureTask (可以拿到返回结果,可以处理异常)
// FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
// new Thread(futureTask).start();
//等待线程完成,执行返回结果
// System.out.println(futureTask.get());
//=================================================4 线程池
//每个异步任务,提交给线程池,让他自己来执行
// service.execute(new Runable01());//直接执行,无返回值
// Future<Integer> submit = service.submit(new Callable01()); //执行,可以获得返回值
// submit.get();
// System.out.println("main......start.....");
}
//1.继承Thread
public static class Thread01 extends Thread {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
}
}
//2.实现Runnable接口
public static class Runable01 implements Runnable {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
}
}
//3.实现Callable接口 + FutureTask (可以拿到返回结果,可以处理异常)
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;
}
}
// 线程池创建
private static void threadPool() {
ExecutorService threadPool = new ThreadPoolExecutor(
200,
10,
10L,
TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(10000),//队列
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
//初始化线程,并提交给线程池进行执行
threadPool.execute(new Runable01());
//定时任务的线程池
ExecutorService service = Executors.newScheduledThreadPool(2);
}
//异步编排
public static void main(String[] args) throws ExecutionException, InterruptedException {
/**
* 异步编程,runAsync没有返回值
* runAsync(Runnable runnable, Executor executor)指定线程池executor
*/
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
}, service);
/**
* 方法完成后的处理,supplyAsync有返回值
*/
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 0;
System.out.println("运行结果:" + i);
return i;
}, service).whenComplete((res,exception) -> {
//虽然能得到异常信息,但是没法修改返回数据
System.out.println("异步任务成功完成了...结果是:" + res + "异常是:" + exception);
}).exceptionally(throwable -> {
//可以感知异常,同时返回默认值
return 10;
});
Integer integer2 = future2.get();
System.out.println(integer2);
/**
* 方法执行完后,对返回的结果进行处理
*/
CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, service).handle((result,thr) -> {
if (result != null) {
return result * 2;
}
if (thr != null) {
System.out.println("异步任务成功完成了...结果是:" + result + "异常是:" + thr);
return 0;
}
return 0;
});
Integer integer = future3.get();
System.out.println("main ---- end "+integer);
/**
* 线程串行化
* 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;
}, service).thenApplyAsync(res -> {
System.out.println("任务2启动了..." + res);
return "Hello" + res;
}, service);
System.out.println("main......end....." + future.get());
}
}
202 CompletableFuture 多任务组合
多任务组合就是将多个CompletableFuture 组合在一起。
allOf()方法和 anyOf()方法的调用