异步&多线程
多线程
多线程创建的几种方式
- 继承Thread
public class Test {
public static void main(String[] args) {
System.out.println("main方法...start");
Thread thread = new Thread01();
thread.start();
System.out.println("main方法...end");
}
public static class Thread01 extends Thread {
@Override
public void run() {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
}
}
}
- 实现Runnable接口
public class Test {
public static void main(String[] args) {
System.out.println("main方法...start");
Runnable01 runnable01 = new Runnable01();
Thread thread = new Thread(runnable01);
thread.start();
System.out.println("main方法...end");
}
public static class Runnable01 implements Runnable {
@Override
public void run() {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
}
}
}
- 实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常)
public class Test {
public static void main(String[] args) {
System.out.println("main方法...start");
FutureTask<Object> futureTask = new FutureTask<>(new Callable01());
Thread thread = new Thread(futureTask);
thread.start();
Object o = null;
try {
//阻塞等待 等待整个线程执行完成,获取返回结果
o = futureTask.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//需要等待获取到返回结果才会进行打印
System.out.println("main方法...end==>" + o);
}
/**
* Callable<Object> ==>Object对应需要返回的结果
*/
public static class Callable01 implements Callable<Object> {
@Override
public Object call() throws Exception {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}
}
}
- 线程池(推荐使用) 以上三种方式创建线程不推荐使用,如果多个请求每次new Thread();可能会导致我们资源耗尽;我们应该将所有的异步线程任务交给线程池执行
/**
* 根据Executors来创建线程池
*/
public class Test {
/**
* 当前系统中池的数量应该只会有一两个(根据自己的业务场景来定);每个异步任务,提交给线程池让它自己去执行
* Executors.newFixedThreadPool(10) 获取一个定长线程池
*/
public static ExecutorService executor = Executors.newFixedThreadPool(10);
/**
* 七个参数
* int corePoolSize :核心线程数【一直存在,除非设置allowCoreThreadTimeOut】,线程池创建好之后就准备就绪的线程数量,就等待来接收异步线程任务去执行
* int maximumPoolSize :最大线程数;控制资源(CPU密集型[CPU核数+1]、IO密集型[CPU核数*2、CPU核数/(1-阻塞系数[0.8~0.9])])
* long keepAliveTime : 存活时间(如果当前线程数量大于核心数量,释放空闲线程[maximumPoolSize-corePoolSize]需要的时间)
* TimeUnit unit : 时间单位
* BlockingQueue<Runnable> workQueue : 阻塞队列。如果任务有很多,就会将目前对的任务放在队列,只要有线程空闲了,就会从队列中取出新的任务继续执行
* ThreadFactory threadFactory : 线程创建工厂
* RejectedExecutionHandler handler : 如果队列满了,按照我们指定的拒绝策略拒绝执行任务(new AbortPolicy()[默认,直接抛出异常阻止系统正常运行]、new DiscardPolicy()[直接丢弃进来的任务]、new DiscardOldestPolicy()[丢弃等待最久的任务]、new CallerRunsPolicy()[不抛弃任务,也不丢弃任务,将任务回退给调用者])
* <p>
* 执行顺序:
* 1.线程池创建好,准备core数量的核心线程,准备接收任务
* 2.如果核心线程数满了,再进来的任务就放入阻塞队列,空闲的线程就自己会去阻塞队列里面获取任务执行
* 3.阻塞队列如果也满了,就会直接开新线程执行,最大开到max指定的数量
* 4.如果max满了,就会使用拒绝策略拒绝任务
* 5.max没满都执行完了,有很多空闲线程;就会在指定的时间(keepAliveTime)以后释放maximumPoolSize-corePoolSize这些线程
* <p>
* 提示:
* new LinkedBlockingDeque<>() 默认是Integer.MAX_VALUE。可能导致内存不够 需要根据压测结果自己指定
*/
public static ThreadPoolExecutor executor01 = new ThreadPoolExecutor(10
, 200
, 10
, TimeUnit.SECONDS
, new LinkedBlockingDeque<>()
, Executors.defaultThreadFactory()
, new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
System.out.println("main方法...start");
// executor.execute(); //无法获取任务返回值
Future<Object> submit = executor.submit(new Callable01());//可以获取任务返回值
Object o = null;
try {
o = submit.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end == >" + o);
}
/**
* Callable<Object> ==>Object对应需要返回的结果
*/
public static class Callable01 implements Callable<Object> {
@Override
public Object call() throws Exception {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}
}
}
线程池几种类型
- Executors.newCachedThreadPool(); //可缓存的线程池 core是0,所有都可以回收
- Executors.newFixedThreadPool(10); //定长线程池,固定大小不可回收
- Executors.newSingleThreadExecutor(); // core是1 单线程池
- Executors.newScheduledThreadPool(10);//定时任务线程池
区别 - 第1、2两种方式不能获取返回值,第3种可以获取返回值
- 第1、2、3种方式不能进行资源控制
- 第4种可以进行资源控制,性能稳定
优点 - 降低资源消耗
- 提供响应速度
- 提供线程的可管理性
CompletableFuture异步编排
创建异步对象
提供了四个静态方法创建异步操作
- public static CompletableFuture runAsync(Runnable runnable) //无返回值
- public static CompletableFuture runAsync(Runnable runnable,Executor executor) //无返回值,可传入自定义的线程池对象
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture.runAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
}, executor);
System.out.println("main方法...end");
}
}
- public static CompletableFuture supplyAsync(Supplier supplier)//有返回值
- public static CompletableFuture supplyAsync(Supplier supplier,Executor executor)//返回值,可传入自定义的线程池对象
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}, executor);
Integer integer = 0;
try {
integer = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end" + integer);
}
}
异步完成回调与异常感知
whenComplete只可以进行感知结果和异常,但是无法对结果进行修改
- public CompletableFuture whenComplete(BiConsumer<? super T, ? super Throwable> action) 执行当前任务的线程继续执行
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}, executor).whenComplete((res, exception) -> {
System.out.println("结果是-->" + res + "异常是-->" + exception);
});
Integer integer = 0;
try {
integer = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end" + integer);
}
}
- public CompletableFuture whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action) 继续提交给线程池进行处理
- public CompletableFuture whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor) 继续提交给线程池进行处理,指定自定义线程池
- public CompletableFuture exceptionally(Function<Throwable, ? extends T> fn) 处理异常情况
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 0;
System.out.println("运行结果---" + num);
return num;
}, executor).whenComplete((res, exception) -> {
System.out.println("结果是-->" + res + "异常是-->" + exception);
}).exceptionally((exception) -> {
//可以感知异常,进行设置默认值
return 10;
});
Integer integer = 0;
try {
integer = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end" + integer);
}
}
handle可对结果进行后续处理
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}, executor).handle((res, exception) -> {
if (res != null) {
return res * 2;
}
if (exception != null) {
return res;
}
return 0;
});
Integer integer = 0;
try {
integer = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end" + integer);
}
}
线程串行化
- public CompletableFuture thenRun(Runnable action)
- public CompletableFuture thenRunAsync(Runnable action)
- public CompletableFuture thenRunAsync(Runnable action,Executor executor) 不能获取上一步的执行结果,无返回值
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}, executor);
future.thenRunAsync(() -> {
System.out.println("任务2启动了....");
}, executor);
System.out.println("main方法...end");
}
}
- public CompletableFuture thenAccept(Consumer<? super T> action)
- public CompletableFuture thenAcceptAsync(Consumer<? super T> action)
- public CompletableFuture thenAcceptAsync(Consumer<? super T> action,Executor executor)能接收上一个线程的执行结果,无返回值
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}, executor);
future.thenAcceptAsync((res) -> {
System.out.println("任务2启动了...."+res);
}, executor);
System.out.println("main方法...end");
}
}
- public CompletableFuture thenApply(Function<? super T,? extends U> fn)
- public CompletableFuture thenApplyAsync(Function<? super T,? extends U> fn)
- public CompletableFuture thenApplyAsync(Function<? super T,? extends U> fn, Executor executor) 能接收上一个线程的执行结果,有返回值
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = future.thenApplyAsync((res) -> {
System.out.println("任务2启动了...." + res);
return res * 2;
}, executor);
Integer integer = 0;
try {
integer = future1.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end" + integer);
}
}
两任务组合-都要完成
- public CompletableFuture runAfterBoth(CompletionStage<?> other,Runnable action)
- public CompletableFuture runAfterBothAsync(CompletionStage<?> other,Runnable action)
- public CompletableFuture runAfterBothAsync(CompletionStage<?> other,Runnable action,Executor executor) 组合两个future,不需要获取future的结果,只需要两个future处理完任务后,处理该任务
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 5;
System.out.println("运行结果1---" + num);
return num;
}, executor);
future.runAfterBothAsync(future1,()->{
System.out.println("任务3开始");
},executor);
System.out.println("main方法...end");
}
}
- public CompletableFuture thenAcceptBoth(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action)
- public CompletableFuture thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action)
- public CompletableFuture thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action,Executor executor) 组合两个future,获取两个future任务的返回结果,然后处理任务,没有返回值
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 5;
System.out.println("运行结果1---" + num);
return num;
}, executor);
future.thenAcceptBothAsync(future1, (res1, res2) -> {
System.out.println("第一个结果的返回值" + res1 + "第二个结果的返回值" + res2);
}, executor);
System.out.println("main方法...end");
}
}
- public <U,V> CompletableFuture thenCombine(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn)
- public <U,V> CompletableFuture thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn)
- public <U,V> CompletableFuture thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn, Executor executor) 组合两个future,获取两个future的返回结果,并返回当前任务的返回值
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 5;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future2 = future.thenCombineAsync(future1, (res1, res2) -> {
System.out.println("第一个结果的返回值" + res1 + "第二个结果的返回值" + res2);
return res1 + res2;
}, executor);
Integer integer = 0;
try {
integer = future2.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end" + integer);
}
}
两任务组合-单个完成
- public CompletableFuture runAfterEither(CompletionStage<?> other,Runnable action)
- public CompletableFuture runAfterEitherAsync(CompletionStage<?> other,Runnable action)
- public CompletableFuture runAfterEitherAsync(CompletionStage<?> other,Runnable action,Executor executor) 组合两个future,两个任务有一个任务执行完,不需要获取返回结果,处理任务没有新的返回结果
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("当前线程1---" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
int num = 10 / 5;
System.out.println("运行结果1---" + num);
return num;
}, executor);
future.runAfterEitherAsync(future1, () -> {
System.out.println("任务3开始....");
}, executor);
System.out.println("main方法...end");
}
}
- public CompletableFuture acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)
- public CompletableFuture acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action)
- public CompletableFuture acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action,Executor executor) 两个任务有一个任务执行完,获取它的返回结果,处理任务没有新的返回结果
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("当前线程1---" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
int num = 10 / 5;
System.out.println("运行结果1---" + num);
return num;
}, executor);
future.acceptEitherAsync(future1, (res) -> {
System.out.println("任务返回结果" + res);
}, executor);
System.out.println("main方法...end");
}
}
- public CompletableFuture applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn)
- public CompletableFuture applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn)
- public CompletableFuture applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn,Executor executor) 两个任务有一个任务执行完,获取它的返回结果,处理任务并返回新的返回结果
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("当前线程1---" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
int num = 10 / 5;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future2 = future.applyToEitherAsync(future1, (res) -> {
System.out.println("任务返回结果" + res);
return res * 2;
}, executor);
Integer integer = 0;
try {
integer = future2.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("main方法...end" + integer);
}
}
多任务组合
- public static CompletableFuture allOf(CompletableFuture<?>... cfs) 等待所有结果完成
public class Test {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("main方法...start");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1---" + Thread.currentThread().getName());
int num = 10 / 2;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
System.out.println("当前线程1---" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
int num = 10 / 5;
System.out.println("运行结果1---" + num);
return num;
}, executor);
CompletableFuture<Void> allOf = CompletableFuture.allOf(future, future1);
try {
// allOf.get();
System.out.println("第一个返回结果" + future.get() + "第二个返回结果" + future1.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
- public static CompletableFuture anyOf(CompletableFuture<?>... cfs) 一个任务完成即可
public class Test { public static ExecutorService executor = Executors.newFixedThreadPool(10); public static void main(String[] args) { System.out.println("main方法...start"); CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> { System.out.println("当前线程1---" + Thread.currentThread().getName()); int num = 10 / 2; System.out.println("运行结果1---" + num); return num; }, executor); CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(3000); System.out.println("当前线程2---" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } int num = 10 / 5; System.out.println("运行结果2---" + num); return num; }, executor); CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future, future1); try { anyOf.get(); System.out.println("返回结果..."); //此处打印先于 当前线程2--- } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }