Java并发41:Executor系列--Executors(上)-Runnable转Callable、ThreadFactory和不可配置的线程池
本章主要学习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();