public class ThreadTest {
// 线程池
public static ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
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((result, exception) -> { // 虽然能够感知异常,但无法修改返回数据
System.out.println("异步任务成功完成。。。结果是:" + result + ";异常是:" + exception);
}).exceptionally(throwable -> {
return 10; // 可感知异常,同时返回默认值
});*/
/** 方法执行完成后的处理 */
// R apply(T t, U u);
/*CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("运行结果:" + i);
return i;
}, executor).handle((result, throwable) -> {
if (result != null) {
return result * 2;
}
if (throwable != null) {
return 0;
}
return 0;
});
Integer result = future.get();
*/
/**
* 线程串行化
* 1)、thenRunAsync:不能获取到上一步的执行结果,无返回值
* 2)、thenAcceptAsync:能接收上一步的结果,无返回值
* 3)、thenApplyAsync:能接收上一步的结果,有返回值
*/
/*CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("运行结果:" + i);
return i;
}, executor).thenRunAsync(() -> {
System.out.println("任务2启动类。。。");
},executor);*/
/*CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("运行结果:" + i);
return i;
}, executor).thenAcceptAsync(result -> {
System.out.println("任务3启动了。。。" + result);
}, executor);*/
/*CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("运行结果:" + i);
return i;
}, executor).thenApplyAsync(result -> {
System.out.println("任务4启动了。。。" + result);
return result;
}, executor);
*/
/**
* 两个都完成
*/
/*CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 4;
System.out.println("任务1结束:");
return i;
}, executor);*/
/*CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
System.out.println("任务2结束:");
return "hello";
}, executor);*/
/*future01.runAfterBothAsync(future02, () -> {
System.out.println("任务3开始。。。");
}, executor);*/
/*future01.thenAcceptBothAsync(future02, (f1, f2) -> {
System.out.println("任务3开始。。。之前的结果:" + f1 + "-->" + f2);
}, executor);*/
/*CompletableFuture<String> future = future01.thenCombineAsync(future02, (f1, f2) -> {
return f1 + ":" + f2;
}, executor);*/
/**
* 两个任务,只要有一个完成,就执行任务3
* runAfterEitherAsync:不感知结果,自己没有返回值
* acceptEitherAsync:感知结果,自己没有返回值
* applyToEitherAsync:感知结果,自己有返回值
*/
/*CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
System.out.println("任务2结束:");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hello";
}, executor);*/
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品图片信息");
return "tokyo_hot.jpg";
}, executor);
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品属性");
return "冰霜银+256G";
}, executor);
CompletableFuture<String> futureIntroduce = CompletableFuture.supplyAsync(() -> {
System.out.println("查询商品介绍");
return "华为";
}, executor);
// CompletableFuture<Void> future = CompletableFuture.allOf(futureImg, futureAttr, futureIntroduce);
// future.get(); // 阻塞等待所有结果完成 //future.join();
// System.out.println("main...end..." + futureImg.get() + "->" + futureAttr.get() + "->" + futureIntroduce.get());
CompletableFuture<Object> future = CompletableFuture.anyOf(futureImg, futureAttr, futureIntroduce);
System.out.println("main...end..." + future.get());
//---------------------
/*CompletableFuture<String> future = future01.applyToEitherAsync(future02, (result) -> {
System.out.println("任务3开始。。。之前的结果是:" + result);
return result.toString();
}, executor);*/
/*future01.acceptEitherAsync(future02, (result) -> {
System.out.println("任务3开始。。。" + result);
}, executor);*/
/*future01.runAfterEitherAsync(future02, () -> {
System.out.println("任务3开始。。。");
}, executor);*/
// System.out.println("main...end...");
}
public void threadTest(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
/**
* 初始化多线程的4种方式
* 1)、 继承Thread
* 2)、 实现Runnable接口
* 3)、实现Callable接口 + FutureTask (可以拿到返回结果,可以处理异常)
* 4)、线程池 给线程池直接提交任务
*
* Future可以获取到异步结果
*
* 区别:1、2这两种方式不能得到返回值。第三种方式可以获取返回值
* 1、2、3都不能控制资源
* 方式4可以控制资源 ,性能稳定。
*/
// 第一种方式:继承Thread
// Thread01 thread = new Thread01();
// thread.start(); // 启动线程
// 第二种方式:实现Runnable接口
// Runnable01 runnable = new Runnable01();
// new Thread(runnable).start();
// 第三种方式:实现Callable接口 + FutureTask (允许有返回值)
// FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
// new Thread(futureTask).start();
// // 【阻塞】等待整个线程执行完成,获取返回结果
// Integer result = futureTask.get();
// System.out.println("main...end..." + result);
/** ---以后再业务代码里面,以上三种启动线程的方式都不用(都如同下面这行代码)。【应该将所有的多线程异步任务交给线程池执行】--- */
// new Thread(() -> System.out.println("hello")).start();
// 第四种方式:线程池
// 当前系统中池只有一两个,每个异步任务直接提交给线程池,让他自己去执行
// service.execute(new Runnable01());
/**
* 七大参数:
* corePoolSize:核心线程数(只要线程池不销毁,一直存在。除非设置allowCoreThreadTimeOut);线程池创建好以后,就准备就绪的线程数量。就等待接收异步任务去执行。
* maximumPoolSize:最大线程数量;控制资源并发
* keepAliveTime:存活时间。如果当前线程数量>核心数量
* unit:时间单位
* BlockingQueue<Runnable> workQueue:阻塞队列。如果任务有很多,就会将目前多地任务放在队列里面。只要有线程空闲,就会去队列里面取出新的任务继续执行。
* threadFactory:线程的创建工厂
* RejectedExecutionHandler handler:如果队列满了,按照我们指定的拒绝策略拒绝执行任务。
*
* 工作顺序:
* 1)、线程池创建,准备好core数量的核心线程,准备接收任务。
* 1.1、core满了,就将再进来的任务放入阻塞队列中,空闲的core就会自己去阻塞队列获取任务执行。
* 1.2、阻塞队列满了,就直接开新线程执行,最大只能开到max指定的数量
* 1.3、max满了,就用RejectedExecutionHandler拒绝任务
* 1.4、max都执行完成,如果有很多空闲,就在指定的时间keepAliveTime以后释放(max - core)这些线程
*
*/
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5,
200,
10,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(10000), // 默认是Integer的最大值。可能内存不够,所以一定要传入业务定制的数量
Executors.defaultThreadFactory(), // 默认的线程工厂
new ThreadPoolExecutor.AbortPolicy()); // 丢弃策略
System.out.println("main...end...");
}
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 Runnable01 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;
}
}
}