Executor
- 只有一个execute方法,入参是一个Runnable 线程
- 实现线程的创建和运行分离
- 是个接口,可以各种实现
ExecutorService
- ExecutorService继承了Executor
- submit 方法,入参是Callable 出参是 Future
- executorService.execute 立马执行
- executorService.submit 交给线程池来执行
Callable
- 创建一个Callable方法,重写call方法(写自己的业务逻辑)
- 创建一个ExecutorService
- 调用submit方法
- 用future接受出参
- Future.get()方法,阻塞方法,直到线程执行结束
- executorService.shutdown()关闭服务
public class thread_pool_01_callable {
public static void main(String[] args) {
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
try{
Thread.sleep(1000);
}catch (Exception e){
}
return 99;
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
try{
Future submit = executorService.submit(callable);
System.out.println(submit.get());
}catch (Exception e){
}finally {
executorService.shutdown(); //关闭
}
}
}
- java8写法
public class thread_pool_02_callable {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
try{
Future submit = executorService.submit(()->{
try{
Thread.sleep(1000);
}catch (Exception e){
}
return 99;
});
System.out.println(submit.get());
}catch (Exception e){
}finally {
executorService.shutdown(); //关闭
}
}
}
Callable 和 Future接口的区别
1 Callable规定的方法是call(),而Runnable规定的方法是run().
2 Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
3 call()方法可抛出异常,而run()方法是不能抛出异常的。
4 运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。 它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
5 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
6 Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
Future
- future.get() 获取当前方法返回值(阻塞方法)
FutureTask
- FutureTask 是 callable 和 future 的组合
- 既能异步实现又能有返回值
public class thread_pool_03_futuretask {
public static void main(String[] args) {
FutureTask futureTask = new FutureTask(()->{
try{
Thread.sleep(1000);
}catch (Exception e){
}
return 999;
});
new Thread(futureTask).start();
try{
System.out.println(futureTask.get());
}catch (Exception e){
}
}
}
ComplatetableFuture
- 多线程执行完成,结果汇总合集
- CompletableFuture.allOf(); 所有线程执行完成
- CompletableFuture.anyOf(jd, tb, tm); 任意一线程执行完成
/**
* @author: lianghengyu
* @time: 2020-05-02
* @desc: 分别调用三大网站, 获取三个网站奥迪的价格 汇总展示
*/
public class thread_pool_04_completablefuture {
public static void main(String[] args) {
long timeMillis = System.currentTimeMillis();
CompletableFuture jd = CompletableFuture.supplyAsync(() ->priceOfJD());
CompletableFuture tb = CompletableFuture.supplyAsync(() ->priceOfTB());
CompletableFuture tm = CompletableFuture.supplyAsync(() ->priceOfTM());
CompletableFuture.allOf(jd, tb, tm);
try{
System.err.println("jd "+jd.get());
System.err.println("tm "+tm.get());
System.err.println("tb "+tb.get());
}catch (Exception e){
}
System.out.println(System.currentTimeMillis()-timeMillis);
}
private static double priceOfTM() {
delay();
return 1.00;
}
private static double priceOfTB() {
delay();
return 2.00;
}
private static double priceOfJD() {
delay();
return 3.00;
}
private static void delay() {
int time = new Random().nextInt(500);
try {
TimeUnit.MILLISECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("After %s sleep!\n", time);
}
}
ThreadPool
- 线程集合
- 任务队列
- 核心线程和最大线程数关系
- 当线程来的时候,先去拿核心线程
- 核心线程用完了,再来线程进任务队列等待
- 当任务队列满了,才增加线程池中的数量,执行任务
public class thread_pool_05_threadpool {
static class Task implements Runnable {
private int i;
public Task(int i) {
this.i = i;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Task " + i);
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "Task{" +
"i=" + i +
'}';
}
}
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 500, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < 3; i++) {
pool.execute(new Task(i));
}
}
}
七大参数
- corePoolSize 核心线程数
- maximumPoolSize 最大线程数
- keepAliveTime 最大线程数保持时间(到期删除)
- TimeUnit 时间类型
- BlockingQueue workQueue 线程队列类型
- ThreadFactory threadFactory 线程工厂
- RejectedExecutionHandler handler 拒绝策略(当任务队列满了,没有空闲线程了)
四种拒绝策略:
- AbortPolicy 直接抛异常
- DiscardPolicy 扔掉,不抛异常
- DiscardOldestPolicy 扔掉队列中最久的线程
- CallerEunsPolicy 调用者处理任务(谁调用,谁来执行他)
更改这个来进行测试
public class T05_00_HelloThreadPool {
static class Task implements Runnable {
private int i;
public Task(int i) {
this.i = i;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Task " + i);
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "Task{" +
"i=" + i +
'}';
}
}
public static void main(String[] args) {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4,
60, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(4),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < 8; i++) {
tpe.execute(new Task(i));
}
System.out.println(tpe.getQueue());
tpe.execute(new Task(100));
System.out.println(tpe.getQueue());
tpe.shutdown();
}
}