package com.huajiyuji.yanfengmall.search.Thred;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
/**
* @Module
* @Description 线程
* @Classname ThredTest
* @Author zyf
* @Create 2021-08-16 11:45
*/
public class ThredTest {
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("------------main------------start");
//1、单任务交给线程池执行
// CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
// String hello = "hello";
// String word = "word";
// String helloWord = hello + word + "Thred";
// System.out.println("任务执行结果-----------------" + helloWord);
// }, executor);
//2、单任务后追加完成回调函数,完成函数可以拿到异常,完成函数没有返回值
// CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
// String hello = "hello";
// String word = "word";
// String helloWord = hello + word + "Thred";
// System.out.println("任务执行结果-----------------" + helloWord + "当前线程是:" + Thread.currentThread());
// return helloWord;
// }, executor).whenComplete((res,throwable)->{
// System.out.println("处理的最终结果是----------" + res +"异常是:" + throwable + "当前线程是:" + Thread.currentThread());
// });
// String s = stringCompletableFuture.get();
// System.out.println("---------返回值----------" + s);
//3、单任务追加异常捕捉函数,异常捕捉函数可以拿到异常,异常捕捉函数有返回值。
// CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
// String hello = "hello";
// String word = "word";
// String helloWord = hello + word + "Thred";
// int a = 10/0;
// System.out.println("任务执行结果-----------------" + helloWord + "当前线程是:" + Thread.currentThread());
// return helloWord;
// }, executor).exceptionally(throwable -> {
// //异常处理回调函数,可以拿到异常,有返回值
// return "出错了";
// });
// String s = stringCompletableFuture.get();
// System.out.println("---------返回值----------" + s);
//4、单任务结束后追加任务处理函数,可以拿到结果、异常、有返回值
// CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
// String hello = "hello";
// String word = "word";
// String helloWord = hello + word + "Thred";
// int a = 10/0;
// System.out.println("任务执行结果-----------------" + helloWord + "当前线程是:" + Thread.currentThread());
// return helloWord;
// }, executor).handle((res,throwable)->{
// if (res != null){
// return res + "handle";
// }
// if (throwable != null){
// return "抛出了异常";
// }
// return "抛出了异常";
// });
// String s = stringCompletableFuture.get();
// System.out.println("---------返回值----------" + s);
//5、单任务后追加异步任务,不能获取到上一步的执行结果,无返回值
// CompletableFuture<Void> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
// String hello = "hello";
// String word = "word";
// String helloWord = hello + word + "Thred";
// System.out.println("任务执行结果-----------------" + helloWord + "当前线程是:" + Thread.currentThread());
// return helloWord;
// }, executor).thenRunAsync(() -> {
// System.out.println("任务2开始执行了");
// }, executor);
//6、单任务后追加新的异步任务,新的异步任务可以获取到上一次任务的执行结果,新任务没有返回值
// CompletableFuture<Void> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
// String hello = "hello";
// String word = "word";
// String helloWord = hello + word + "Thred";
// System.out.println("任务执行结果-----------------" + helloWord + "当前线程是:" + Thread.currentThread());
// return helloWord;
// }, executor).thenAcceptAsync((res) -> {
// System.out.println("任务2开始执行了,任务1的结果是---"+res);
// }, executor);
//7、单任务后追加新的异步任务,并可以接受上次任务执行的结果,有返回值
// CompletableFuture<List<Integer>> completableFuture = CompletableFuture.supplyAsync(() -> {
// String hello = "hello";
// String word = "word";
// String helloWord = hello + word + "Thred";
// System.out.println("任务执行结果-----------------" + helloWord + "当前线程是:" + Thread.currentThread());
// return helloWord;
// }, executor).thenApplyAsync((res)->{
// System.out.println("第一次的执行结果为------"+res);
// Integer[] a = {1,2,3};
// return Arrays.asList(a);
// },executor);
// System.out.println("线程池最终返回结果为------" + completableFuture.get().toString());
//8、任务1、任务2异步执行结束后,开启新的异步任务3,异步任务3可以拿到任务1、2的返回值,任务3也有返回值
// CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务1执行-----------------当前线程是:" + Thread.currentThread());
// return "任务1";
// }, executor);
// CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务2执行-----------------当前线程是:" + Thread.currentThread());
// return 222;
// }, executor);
// CompletableFuture<String> future3 = future1.thenCombineAsync(future2, (res1, res2) -> {
// System.out.println("任务3执行---------任务1执行结果------" + res1 + "------------任务2执行结果" + res2 + "----当前线程是:" + Thread.currentThread());
// return "任务3执行结果";
// }, executor);
// System.out.println("任务3返回的结果为----------------" + future3.get());
//9、任务1、任务2执行结束后,开启新的异步任务3,异步任务3可以拿到任务1、2的返回值,任务3无返回值
// CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务1执行-----------------当前线程是:" + Thread.currentThread());
// return "任务1";
// }, executor);
// CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务2执行-----------------当前线程是:" + Thread.currentThread());
// return 222;
// }, executor);
// future1.thenAcceptBothAsync(future2,(res1,res2)->{
// System.out.println("----任务3执行了--------------------任务1的结果为:" + res1 + "----任务2的结果为-----" + res2);
// },executor);
//10、任务1、2只要有一个完成,就会执行异步任务3,任务3不感知任务1、2的结果,也没有返回值。
// CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务1执行-----------------当前线程是:" + Thread.currentThread());
// return "任务1";
// }, executor);
// CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("任务2执行-----------------当前线程是:" + Thread.currentThread());
// return 222;
// }, executor);
// future1.runAfterEitherAsync(future2,()->{
// System.out.println("任务3开始执行了-----当前线程为" + Thread.currentThread());
// },executor);
//11、任务1、2只要有一个完成,就会执行异步任务3,任务3可以感知任务1、2的结果,没有返回值。
// CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务1执行-----------------当前线程是:" + Thread.currentThread());
// return "任务1";
// }, executor);
// CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务2执行-----------------当前线程是:" + Thread.currentThread());
// return "任务2";
// }, executor);
// future1.acceptEitherAsync(future2, (res) -> {
// System.out.println("任务3开始执行,接到的参数是-----------" + res);
// }, executor);
//12、任务1、2只要有一个完成,就会执行异步任务3,任务3可以感知任务1、2的结果,并且有返回值。
// CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务1执行-----------------当前线程是:" + Thread.currentThread());
// return "任务1";
// }, executor);
// CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务2执行-----------------当前线程是:" + Thread.currentThread());
// return "任务2";
// }, executor);
// CompletableFuture<String> stringCompletableFuture = future1.applyToEitherAsync(future2, (res) -> {
// System.out.println("任务3开始执行,接收到的参数是:" + res);
// return "任务3返回值";
// }, executor);
//13、任务1、2、3全部执行完成之后再继续处理新任务。
// CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务1执行-----------------当前线程是:" + Thread.currentThread());
// return "任务1";
// }, executor);
// CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务2执行-----------------当前线程是:" + Thread.currentThread());
// return "任务2";
// }, executor);
// CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
// System.out.println("任务3执行-----------------当前线程是:" + Thread.currentThread());
// return "任务3";
// }, executor);
// CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
// allOf.get();
//14、任务1、2、3任何一个处理完成之后继续处理新任务。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1执行-----------------当前线程是:" + Thread.currentThread());
return "任务1";
}, executor);
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2执行-----------------当前线程是:" + Thread.currentThread());
return "任务2";
}, executor);
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务3执行-----------------当前线程是:" + Thread.currentThread());
return "任务3";
}, executor);
CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(future1, future2, future3);
objectCompletableFuture.get();
System.out.println("------------main------------end");
}
public void test(String[] args) throws ExecutionException, InterruptedException {
/**
* 1、继承Thred类
* System.out.println("多线程任务开始--------------------");
* MyThred myThred = new MyThred();
* myThred.start();
* System.out.println("多线程任务结束--------------------");
* 2、实现Runable接口
* System.out.println("多线程任务开始--------------------");
* Thread thread = new Thread(new MyRuanable());
* thread.start();
* System.out.println("多线程任务结束--------------------");
* 3、实现Callable接口
* System.out.println("多线程任务开始--------------------");
* FutureTask<String> myCallableFutureTask = new FutureTask(new MyCallable());
* Thread thread = new Thread(myCallableFutureTask);
* thread.start();
* String s = myCallableFutureTask.get();
* System.out.println(s);//如果拿返回值这线程阻塞
* System.out.println("多线程任务结束--------------------");
* 4、线程池 [ExecutorService]
* System.out.println("多线程任务开始--------------------");
* Future<String> submit = service.submit(new MyCallable());
* String s = submit.get();
* System.out.println(s);
* System.out.println("多线程任务结束--------------------");
*
* 4.1、创建
* 4.1.1、Executors
* 4.1.2、new ThreadPoolExecutor()
* 七大参数:int corePoolSize, 线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize
* int maximumPoolSize, 一个任务被提交到线程池以后,首先会找有没有空闲存活线程,如果有则直接将任务交给这个空闲线程来执行,如果没有则会缓存到工作队列(后面会介绍)中,如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定
* long keepAliveTime, 一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定
* TimeUnit unit, 空闲线程存活时间单位
* BlockingQueue<Runnable> workQueue, 如果任务有很多, 超出最大线程数,则先保存到阻塞队列中,只要有空闲的线程,则会从该队列中取数据继续执行 。new LinkedBlockingQueue<>() 默认队列可保存任务数量为Integer最大值,需要按需调整
* ThreadFactory threadFactory, 线程的创建工厂
* RejectedExecutionHandler handler 如果阻塞队列溢出,则由handler处理
* 工作顺序:1、线程池创建,准备好核心线程core数量的核心线程,准备接受任务
* 2、core满了就将任务存放在阻塞队列中,core从任务队列中依次取数据执行
* 3、如果队列也满了就直接开辟新的线程,最大只能开辟到maximumPoolSize
* 4、如果max满了就用RejectedExecutionHandler拒绝接受新的任务
* 5、如果所有的任务都执行完了,在等待时间超过keepAliveTime时会销毁 maximumPoolSize 减去 corePoolSize 个线程
*
*
* 一个线程池:7个core线程,maximumPoolSize为20,BlockingQueue最大容量为50,则100个任务过来时,任务是怎么执行的
* 首先7个core线程分配7个任务,队列缓存50个任务,接下来在开13个线程,其余任务采用拒绝策略处理
*
*
* 总结:1、2不能拿到返回值,3可以拿到返回值,1、2、3不能控制资源 4可以控制资源,性能稳定
* 系统业务中推荐使用线程池,避免无限制的创建线程导致资源枯竭
*/
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
20,
10,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
//Executors.newCachedThreadPool(); core为0的线程池,所有新建线程都可以回收
//Executors.newFixedThreadPool(); core和最大可开线程数相等的线程池,所有线程都不可以回收
//Executors.newScheduledThreadPool(); 定时任务线程池
//Executors.newSingleThreadExecutor(); 单线程的线程池,可保证任务顺序执行
}
//1、继承Thred类
public static class MyThred extends Thread {
@Override
public void run() {
String hello = "hello";
String word = "word";
String helloWord = hello + word + "Thred";
System.out.println("任务执行结果-----------------" + helloWord);
}
}
//2、实现RunAble接口
public static class MyRuanable implements Runnable{
@Override
public void run() {
String hello = "hello";
String word = "word";
String helloWord = hello + word + "Runable";
System.out.println("任务执行结果-----------------" + helloWord);
}
}
//3、实现Callable接口
public static class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
String hello = "hello";
String word = "word";
String helloWord = hello + word + "Callable";
System.out.println("任务执行结果-----------------" + helloWord);
return helloWord;
}
}
}