本章主要学习Executors接口。
1.Executors接口概述
@since 1.5
这个类定义了供Executor、ExecutorService、ScheduledExecutorService、ThreadFactory和Callable这些接口和类使用的工厂方法和工具方法。
Executors来自java.util.concurrent,是Executor并发框架的主要工具类。
Executors提供了以下几类方法:
- 第1类静态方法:将Runnable转换成Callable。
- 第2类静态方法:线程工厂(ThreadFactory)类。
- 第3类静态方法:实例化几类不可配置的线程池(ExecutorService和ScheduleExecutorService)。
- 第4类静态方法:实例化几类预先配置的常用线程池(ExecutorService)。
- 第5类静态方法:实例化几类预先配置的常用可调度线程池(ScheduleExecutorService)。
本章主要对第1、2、3类静态方法进行说说明。
2.第1类静态方法:将Runnable转换成Callable
通过前面的学习,我们知道Runnable并不能返回运行结果,在某些应用场景下,这种缺陷是很不不方便的。
而Callable作为一种新的线程实现方式,能够返回值。
Executors工具类提供了一系列方法用于将Runnable转化成Callable,下面列出两种:
- Executors.callable(runnable):将Runnable对象转化成
Callable<Object>
对象,与之结合的Future对象返回null。 - Executors.callable(runnable, result):将Runnable对象转化成
Callable<V>
对象,与之结合的Future对象返回result。
下面,分别对上述两个方法进行实例编码:
//定义运行结果
final Integer[] result = {null};
//定义一个Runnable接口
Runnable runnable = new Runnable() {
@Override
public void run() {
result[0] = 111111;
}
};
//定义一个线程池
ExecutorService executorService = Executors.newCachedThreadPool();
//Executors.callable(runnable)=转换成Callable<Object>,Future返回null
Callable<Object> callable = Executors.callable(runnable);
//提交转换成之后的Callable接口
Future future = executorService.submit(callable);
//输出运行结果,肯定是null
System.out.println("Executors.callable(runnable) 的future = " + future.get());
//Executors.callable(runnable, result)=转换成Callable<V>,future有值
Callable<Integer> callable1 = Executors.callable(runnable, result[0]);
//提交转换成之后的Callable接口
Future future1 = executorService.submit(callable1);
//输出运行结果
System.out.println("Executors.callable(runnable, result) 的future = " + future1.get());
运行结果:
Executors.callable(runnable) 的future = null
Executors.callable(runnable, result) 的future = 111111
3.第2类静态方法:线程工厂(ThreadFactory)类
线程工厂(ThreadFactory)类提供了线程创建的工厂方法。
通过线程工厂创建的线程位于同一线程组(ThreadGroup),并且拥有相同的优先级(priority)。
创建线程工厂(ThreadFactory)类的方法如下:
- Executors.defaultThreadFactory()
下面对这个方法进行实例编码练习:
//创建线程工厂
ThreadFactory threadFactory = Executors.defaultThreadFactory();
//创建多个线程
for (int i = 0; i < 5; i++) {
Thread thread = threadFactory.newThread(() -> {
System.out.println(Thread.currentThread() + " : " + 22222);
});
//执行此线程
thread.start();
}
运行结果:
Thread[pool-2-thread-1,5,main] : 22222
Thread[pool-2-thread-2,5,main] : 22222
Thread[pool-2-thread-3,5,main] : 22222
Thread[pool-2-thread-5,5,main] : 22222
Thread[pool-2-thread-4,5,main] : 22222
可以看到,这些线程都属于同一线程组main,且优先级都是默认优先级5。
4.第3类静态方法:不可配置的线程池
Executors类提供了以下两类静态方法,用于创建不可配置的线程池:
- Executors.unconfigurableExecutorService(executorService):不可配置的线程池
- Executors.unconfigurableScheduledExecutorService(scheduledExecutorService):不可配置的调度线程池
不可配置的线程池通过代理线程池对象DelegatedExecutorService来禁止方法的强制转换。
这种方式提供了一种安全地“冻结”配置并且不允许调整给定具体实现的方法。
我本身并没有对这两个方法进行实际编码,只是对齐进行基本了解,其使用思路大概如下:
//定义一个线程池服务ExecutorService
ExecutorService executorService1 = null;
//将上述的线程池服务ExecutorService 转换成 不可配置的线程池服务
ExecutorService unconfigurableExecutorService = Executors.unconfigurableExecutorService(executorService1);
//...业务操作
//关闭服务
unconfigurableExecutorService.shutdownNow();
//定义一个可调度的线程池服务ScheduledExecutorService
ScheduledExecutorService scheduledExecutorService = null;
//将上述的线程池服务ScheduledExecutorService 转换成 不可配置的可调度的线程池服务
ScheduledExecutorService unconfigurableScheduledExecutorService = Executors.unconfigurableScheduledExecutorService(scheduledExecutorService);
//...业务操作
//关闭服务
unconfigurableScheduledExecutorService.shutdown();