当我们有任务需要多线程来完成时,将任务(实现Runnable、callable接口、继承Thread类的对象)提交给ExecutorService。
1.创建ExecutorService
public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线 程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持延迟及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
ExecutorService executorService2 = Executors.newFixedThreadPool(10);
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
以上的工具类的具体实现都是基于ThreadPoolExecutor类,处理策略都是AbortPolicy(直接抛出异常,阻止系统正常工作)
通常情况下,线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
2.ExecutorService的执行
2.1execute(Runnable)
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
executorService.shutdown();
2.2submit(Runnable)
Future future = executorService.submit(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
future.get(); //returns null if the task has finished correctly.
2.3submit(Callable)
Future future = executorService.submit(new Callable(){
public Object call() throws Exception {
System.out.println("Asynchronous Callable");
return "Callable Result";
}
});
System.out.println("future.get() = " + future.get());
2.4invokeAny(…)
ExecutorService executorService = Executors.newSingleThreadExecutor();
Set<Callable<String>> callables = new HashSet<Callable<String>>();
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 1";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 2";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 3";
}
});
String result = executorService.invokeAny(callables);
System.out.println("result = " + result);
executorService.shutdown();
2.5invokeAll(…)
ExecutorService executorService = Executors.newSingleThreadExecutor();
Set<Callable<String>> callables = new HashSet<Callable<String>>();
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 1";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 2";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 3";
}
});
List<Future<String>> futures = executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}
executorService.shutdown();
3.example
@Configuration
public class ExecutorConfig {
private static final int QUEUE_SIZE = 100_000;
@Bean
public ExecutorService dogTaskExecutor() {
return ExecutorUtil.genExecutorService("dogTask", 50, QUEUE_SIZE);
}
@Bean
public ExecutorService catBagExecutor() {
return ExecutorUtil.genExecutorService("cat", 50, QUEUE_SIZE);
}
}
public class ExecutorUtil {
public static ExecutorService genExecutorService(String name, int currency, int queue) {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat(name + "-%d").build();
ExecutorService executorService = new ThreadPoolExecutor(currency, currency*2, 60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(queue), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
return TtlExecutors.getTtlExecutorService(executorService);
}
}