异步和线程池问题
package com.song.gulimall.gulimallsearch.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/* *
* @program: gulimall
* @description
* @author: swq
* @create: 2021-03-24 10:52
**/
public class ThreadTest {
public static ExecutorService service = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main....start");
/**
* 1、继承Thread类
* 2、实现Runnable接口
* 3、实现Callable接口 结合FutureTask使用
* 4、线程池 给线程池直接提交任务
*/
// 1、继承Thread类
Thread01 thread01 = new Thread01();
thread01.start();
// 实现Runnable接口
Runnable01 runnable01 =new Runnable01();
Thread thread=new Thread(runnable01);
thread.start();
// 实现Callable接口
Callable01 callable01 =new Callable01();
FutureTask<Integer> futureTask = new FutureTask<>(callable01);
new Thread(futureTask).start();
// 阻塞等待整个线程运行完成,返回运行结果
Integer integer = futureTask.get();
System.out.println(integer);
// 使用线程池
service.execute(new Runnable01());
System.out.println("main....end");
}
/* *
* 实现Callable接口 结合FutureTask使用
*/
public static class Callable01 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}
}
/* *
* 实现Runnable接口
*/
public static class Runnable01 implements Runnable{
@Override
public void run() {
System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
}
}
/* *
* 继承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);
}
}
}
线程池
创建一个线程池的流程:
/**
* int corePoolSize,
* int maximumPoolSize,
* long keepAliveTime,
* TimeUnit unit,
* BlockingQueue<Runnable> workQueue,
* ThreadFactory threadFactory,
* RejectedExecutionHandler handler
*/
ThreadPoolExecutor threadPoolExecutor =new ThreadPoolExecutor(5,
200,
10,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(10000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
参数含义:
面试题:
常见的线程池
1.newFixedThreadPool:创建定长的线程池,超出定长在线程队列中等待。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
2.newCachedThreadPool:线程数无限大,当线程队列中有空闲线程时会复用,否则重新创建线程,同时线程60s没有用时,从线程队列中移除。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
3.newScheduledThreadPool:次线程池是在规定的时间进行调度。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
4.newSingleThreadExecutor:仅有一个线程在调度,且有顺序的进行出队和入队。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
但是他们都调用了ThreadPoolExecutor:看一下核心构造器里的几个参数
- corePoolSize: 要保留在池中的线程数量。
- maximumPoolSize:线程池中允许的最大线程数。
- keepAliveTime:空闲线程等待的最大时间。
- unit:keepAliveTime的时间单位。
- workQueue:可执行的任务队列。
- threadFactory:执行创建一个新的线程时使用。
- handler:当达到了线程边界和队列容量,执行被阻塞时使用的处理程序
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
CompletableFuture异步编排
测试运行
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main....start");
// 不带返回值
// CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
// System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
// int i = 10 / 2;
// System.out.println(i);
// }, executor);
// 带返回值
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}, executor);
System.out.println("future...." + future.get());
System.out.println("main....end");
}
带有Async的是异步执行,通知线程池挑选空闲线程执行下一步操作,不带Async的是同步操作,当前线程在执行完毕后,再去执行其他的操作。
// 带返回值
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 0;
System.out.println(i);
return i;
}, executor).whenComplete((result, exception) -> {
System.out.println("执行成功的结果。。。。" + result + ";异常时。。。" + exception);
}).exceptionally((throwable) -> { // 如果发生异常 执行默认返回值
return 10;
});
exceptionally 只能感知异常,不能处理结果。
handle不管有无异常异常,都能处理结果。
// 线程串行化 thenRunAsync 不接受上一步的返回值
CompletableFuture.supplyAsync(() -> {
System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}, executor).thenRunAsync(() -> {
System.out.println("任务2 当前线程号。。。。。" + Thread.currentThread().getId());
},executor);
// 线程串行化 thenAcceptAsync 接受上一步的返回值 无返回值
CompletableFuture.supplyAsync(() -> {
System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}, executor).thenAcceptAsync((result) -> {
System.out.println("上一步的执行结果是。。。" + result);
System.out.println("任务2 当前线程号。。。。。" + Thread.currentThread().getId());
}, executor);
// 线程串行化 thenApplyAsync 接受上一步的返回值 有返回值
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("Runnable 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}, executor).thenApplyAsync((result) -> {
System.out.println("上一步的执行结果是。。。" + result);
System.out.println("任务2 当前线程号。。。。。" + Thread.currentThread().getId());
return 5;
}, executor);
System.out.println("future...." + future.get());
测试 runAfterBothAsync
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}, executor);
CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2 当前线程号。。。。。" + Thread.currentThread().getId());
return "Hello";
}, executor);
future01.runAfterBothAsync(future02, () -> {
System.out.println("任务3.....");
}, executor);
thenAcceptBothAsync 可以接受参数 无返回值
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}, executor);
CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2 当前线程号。。。。。" + Thread.currentThread().getId());
return "Hello";
}, executor);
future01.thenAcceptBothAsync(future02, (f1, f2) -> {
System.out.println("任务3....." + "f1的結果" + f1 + "=======f2的結果" + f2);
}, executor);
thenCombineAsync 有入参 有返回值
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1 当前线程号。。。。。" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println(i);
return i;
}, executor);
CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2 当前线程号。。。。。" + Thread.currentThread().getId());
return "Hello";
}, executor);
CompletableFuture<Integer> future = future01.thenCombineAsync(future02, (f1, f2) -> {
System.out.println("任务3....." + "f1的結果" + f1 + "=======f2的結果" + f2);
return 999;
}, executor);
System.out.println(future.get());
runAfterEitherAsync 无入参 无返回值
acceptEitherAsync 有入参 无返回值
applyToEitherAsync 有入参 有返回值