相关文章:
这次主要整理下 Java 中 ThreadPoolExecutor 类的常用方法
一、ThreadPoolExecutor 类定义
-
ThreadPoolExecutor 类位于 java.util.concurrent 包中,主要用于创建线程池
-
ThreadPoolExecutor 类提供四个构造函数来实例化 ThreadPoolExecutor 对象
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
-
由源码可知,前面三个构造函数内部都是调用第四个构造函数来实现的
-
构造函数七个参数含义如下
参数名 含义 corePoolSize 核心线程数 maximumPoolSize 最大线程数 keepAliveTime 非核心线程的最大存活时间 unit keepAliveTime 参数的时间单位 workQueue 工作队列 threadFactory 线程创建工厂 handler 线程拒绝策略
-
-
ThreadPoolExecutor 类包含四个线程拒绝策略
拒绝策略 含义 AbortPolicy 直接丢弃任务,抛出异常 (默认策略) CallerRunsPolicy 将任务分配给调用线程来执行 DiscardPolicy 直接丢弃任务,不抛出异常 DiscardOldestPolicy 丢弃队列中最早的任务,不抛出异常
二、ThreadPoolExecutor 类常用方法
创建一个线程池,用于下面例子调用
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 10,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(10),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
-
getPoolSize()
-
获取线程池中当前的线程数
executor.execute(() -> System.out.println("Hello World")); System.out.println(executor.getPoolSize()); // 1 executor.shutdown();
-
-
getLargestPoolSize()
-
获取线程池中同时存在的最大线程数
-
largestPoolSize <= maximunPoolSize
executor.execute(() -> System.out.println("Hello World")); System.out.println(executor.getLargestPoolSize()); // 1 executor.shutdown();
-
-
getCorePoolSize()
-
获取核心线程数
System.out.println(executor.getCorePoolSize()); // 5
-
-
setCorePoolSize(int corePoolSize)
-
设置核心线程数
executor.setCorePoolSize(10); System.out.println(executor.getCorePoolSize()); // 10
-
-
getMaximumPoolSize()
-
获取最大线程数
System.out.println(executor.getMaximumPoolSize()); // 10
-
-
setMaximumPoolSize(int maximumPoolSize)
-
设置最大线程数
executor.setMaximumPoolSize(20); System.out.println(executor.getMaximumPoolSize()); // 20
-
-
getKeepAliveTime(TimeUnit unit)
-
获取线程最大存活时间 (该线程指的是非核心线程)
System.out.println(executor.getKeepAliveTime(TimeUnit.SECONDS)); // 10
-
-
setKeepAliveTime(long time, TimeUnit unit)
-
设置线程最大存活时间 (该线程指的是非核心线程)
executor.setKeepAliveTime(20, TimeUnit.SECONDS); System.out.println(executor.getKeepAliveTime(TimeUnit.SECONDS)); // 20
-
-
getQueue()
-
获取工作队列
-
当线程数大于核心线程数且小于最大线程数时,提交的新任务会放入到队列中
-
此种情况,当前线程数为 5,小于等于核心线程数,因此不会有任务放入到队列中
IntStream.range(0, 5).forEach(i -> executor.execute(() -> System.out.println("Hello World"))); System.out.println(executor.getQueue()); executor.shutdown(); // Hello World // Hello World // Hello World // Hello World // Hello World // []
-
此种情况,当前线程数为 6,大于核心线程数,因此会有任务放入到队列中
IntStream.range(0, 6).forEach(i -> executor.execute(() -> System.out.println("Hello World"))); System.out.println(executor.getQueue()); executor.shutdown(); // Hello World // Hello World // Hello World // Hello World // Hello World // Hello World // [clazz.ThreadPoolExecutorTest$$Lambda$2/1023892928@4dd8dc3]
-
-
-
getThreadFactory()
-
获取线程创建工厂
System.out.println(executor.getThreadFactory()); // java.util.concurrent.Executors$DefaultThreadFactory@3d075dc0
-
-
setThreadFactory(ThreadFactory threadFactory)
-
设置线程创建工厂
executor.setThreadFactory(Executors.defaultThreadFactory()); System.out.println(executor.getThreadFactory()); // java.util.concurrent.Executors$DefaultThreadFactory@682a0b20
-
-
getRejectedExecutionHandler()
-
获取线程拒绝策略
System.out.println(executor.getRejectedExecutionHandler()); // java.util.concurrent.ThreadPoolExecutor$AbortPolicy@214c265e
-
-
setRejectedExecutionHandler(RejectedExecutionHandler handler)
-
设置线程拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); System.out.println(executor.getRejectedExecutionHandler()); // java.util.concurrent.ThreadPoolExecutor$DiscardPolicy@682a0b20
-
-
getActiveCount()
-
获取正在执行任务的大致线程数
executor.execute(() -> System.out.println("Hello World")); System.out.println(executor.getActiveCount()); // 1 executor.shutdown();
-
-
getTaskCount()
-
获取已安排执行的大致任务总数
-
因为任务和线程的状态可能在计算期间动态改变,所以获取到的只是近似值
executor.execute(() -> System.out.println("Hello World")); System.out.println(executor.getTaskCount()); // 1 executor.shutdown();
-
-
getCompletedTaskCount()
-
获取已完成执行的大致任务总数
-
因为任务和线程的状态可能在计算期间动态改变,所以获取到的只是近似值
executor.execute(() -> System.out.println("Hello World")); System.out.println(executor.getCompletedTaskCount()); // 1 executor.shutdown();
-
-
execute(Runnable command)
-
执行给定的 Runnable 任务
executor.execute(() -> System.out.println("Hello World")); // Hello World executor.shutdown();
-
-
submit(Runnable task)
-
提交给定的 Runnable 任务进行执行,在任务执行完成后,返回相应的 Future
-
Future 的 get() 方法会在任务执行完成后返回 null
Future<?> submit1 = executor.submit(() -> System.out.println("Hello World")); System.out.println(submit1.get()); // null executor.shutdown();
-
-
submit(Callable task)
-
提交给定的 Callable 任务进行执行,在任务执行完成后,返回相应的 Future
-
Future 的 get() 方法会在任务执行完成后返回任务结果
Future<Object> submit2 = executor.submit(() -> "Hello World"); System.out.println(submit2.get()); // Hello World executor.shutdown();
-
-
submit(Runnable task, T result)
-
提交给定的 Runnable 任务进行执行,在任务执行完成后,返回相应的 Future
-
Future 的 get() 方法会在任务执行完成后返回给定的任务结果
Future<String> submit = executor.submit(() -> System.out.println("Hello World"), "result"); System.out.println(submit.get()); // result executor.shutdown();
-
-
invokeAll(Collection<? extends Callable> tasks)
-
执行给定的 Callable 任务列表,在所有任务执行完成后,返回相应的 Future 列表
-
Future 的 get() 方法会在任务执行完成后返回给定的任务结果
Callable<String> task1 = () -> "Hello World1"; Callable<String> task2 = () -> "Hello World2"; List<Callable<String>> callableList = Arrays.asList(task1, task2); List<Future<String>> futureList = executor.invokeAll(callableList); for (Future<String> future : futureList) { System.out.println(future.get()); } executor.shutdown(); // Hello World1 // Hello World2
-
-
invokeAll(Collection<? extends Callable> tasks, long timeout, TimeUnit unit)
-
执行给定的 Callable 任务列表,在所有任务执行完成后,返回相应的 Future 列表
-
针对所有任务,进行了超时时间控制,如果超时,会取消所有没有未完成的任务,并抛出 CancellationException 异常
Callable<String> task1 = () -> "Hello World1"; Callable<String> task2 = () -> { TimeUnit.SECONDS.sleep(2); return "Hello World2"; }; List<Callable<String>> callableList = Arrays.asList(task1, task2); List<Future<String>> futureList = executor.invokeAll(callableList, 1, TimeUnit.SECONDS); for (Future<String> future : futureList) { System.out.println(future.get()); } executor.shutdown(); // Hello World1 // Exception in thread "main" java.util.concurrent.CancellationException // at java.util.concurrent.FutureTask.report(FutureTask.java:121) // at java.util.concurrent.FutureTask.get(FutureTask.java:192) // at clazz.ThreadPoolExecutorTest.main(ThreadPoolExecutorTest.java:55)
-
-
invokeAny(Collection<? extends Callable> tasks)
-
执行给定的任务列表,在有一个任务成功执行完成后,就会返回相应的任务结果,其余任务会被取消
Callable<String> task1 = () -> "Hello World1"; Callable<String> task2 = () -> "Hello World2"; List<Callable<String>> callableList = Arrays.asList(task1, task2); String result = executor.invokeAny(callableList); System.out.println(result); // Hello World1 executor.shutdown();
-
-
invokeAny(Collection<? extends Callable> tasks, long timeout, TimeUnit unit)
-
执行给定的任务列表,在有一个任务成功执行完成后,就会返回相应的任务结果
-
针对所有任务,进行了超时时间控制,如果超时,会取消超时任务,直到有任务成功执行为止
-
如果所有任务都超时,则会抛出 TimeoutException 异常
Callable<String> task1 = () -> { TimeUnit.SECONDS.sleep(2); return "Hello World1"; }; Callable<String> task2 = () -> "Hello World2"; List<Callable<String>> callableList = Arrays.asList(task1, task2); String result = executor.invokeAny(callableList, 1, TimeUnit.SECONDS); System.out.println(result); // Hello World2 executor.shutdown();
Callable<String> task1 = () -> { TimeUnit.SECONDS.sleep(2); return "Hello World1"; }; Callable<String> task2 = () -> { TimeUnit.SECONDS.sleep(2); return "Hello World2"; }; List<Callable<String>> callableList = Arrays.asList(task1, task2); String result = executor.invokeAny(callableList, 1, TimeUnit.SECONDS); System.out.println(result); executor.shutdown(); // Exception in thread "main" java.util.concurrent.TimeoutException // at java.util.concurrent.AbstractExecutorService.doInvokeAny(AbstractExecutorService.java:184) // at java.util.concurrent.AbstractExecutorService.invokeAny(AbstractExecutorService.java:225) // at clazz.ThreadPoolExecutorTest.main(ThreadPoolExecutorTest.java:75)
-
-
isShutdown()
-
如果线程池已关闭,则返回 true;否则返回 false
executor.execute(() -> System.out.println("Hello World")); executor.shutdown(); System.out.println(executor.isShutdown()); // true
-
-
isTerminated()
-
如果在线程池关闭后,所有任务都已完成,则返回 true;否则返回 false
-
此外,除非先调用 shutdown() 方法 或 shutdownDown() 方法,否则 isTerminated() 永远为 false
-
此种情况,执行 execute() 方法的线程晚于主线程执行完毕,因此 isTerminated() 方法返回 false
executor.execute(() -> System.out.println("Hello World")); executor.shutdown(); System.out.println(executor.isTerminated()); // false
-
此种情况,让主线程休眠 100 ms,使执行 execute() 方法的线程先执行完毕,因此 isTerminated() 方法返回 true
executor.execute(() -> System.out.println("Hello World")); executor.shutdown(); TimeUnit.MILLISECONDS.sleep(100); System.out.println(executor.isTerminated()); // true
-
-
-
isTerminating()
-
如果线程池在执行了 shutdown() 方法或 shutdownNow() 方法后,尚有任务未执行完成,则返回 true;否则返回 false
-
此种情况,执行 execute() 方法的线程晚于主线程执行完毕,因此 isTerminating() 方法返回 true
executor.execute(() -> System.out.println("Hello World")); executor.shutdown(); System.out.println(executor.isTerminating()); // true
-
此种情况,让主线程休眠 100 ms,使执行 execute() 方法的线程先执行完毕,因此 isTerminating() 方法返回 false
executor.execute(() -> System.out.println("Hello World")); executor.shutdown(); TimeUnit.MILLISECONDS.sleep(100); System.out.println(executor.isTerminating()); // false
-
-
-
shutdown()
-
关闭线程池
-
正在执行的任务会继续执行,尚未执行的任务不再处理
-
-
shutdownNow()
-
立刻关闭线程池
-
中止所有正在执行的任务,尚未执行的任务不再处理
-
-
prestartCoreThread()
-
启动一个核心线程,使其等待执行任务,返回 true
-
此方法会覆盖在执行新任务时,启动核心线程的默认策略
-
如果所有核心线程均已启动,则调用此方法会返回 false
System.out.println(executor.prestartCoreThread()); // ture System.out.println(executor.getPoolSize()); // 1 executor.shutdown();
IntStream.range(0, 5).forEach(i -> executor.execute(() -> System.out.println("Hello World"))); System.out.println(executor.prestartCoreThread()); // false System.out.println(executor.getPoolSize()); // 5 executor.shutdown();
-
-
prestartAllCoreThreads()
-
启动所有核心线程,使其等待执行任务
-
此方法会覆盖在执行新任务时,启动核心线程的默认策略
System.out.println(executor.prestartAllCoreThreads()); // 5 System.out.println(executor.getPoolSize()); // 5 executor.shutdown();
-
-
allowCoreThreadTimeOut(boolean value)
-
设置是否允许核心线程超时
executor.prestartAllCoreThreads(); executor.allowCoreThreadTimeOut(true); System.out.println(executor.getPoolSize()); // 5 TimeUnit.SECONDS.sleep(15); System.out.println(executor.getPoolSize()); // 0
-
-
allowsCoreThreadTimeOut()
-
获取核心线程是否可以超时的标识
executor.allowCoreThreadTimeOut(true); System.out.println(executor.allowsCoreThreadTimeOut()); // true executor.allowCoreThreadTimeOut(false); System.out.println(executor.allowsCoreThreadTimeOut()); // false
-
-
awaitTermination(long timeout, TimeUnit unit)
-
设置超时时间,当线程池关闭后,阻塞主线程直到所有任务都执行完毕,或者超时
-
此种情况,任务执行完毕时间小于超时时间,即所有线程都已执行完毕,返回 true
executor.execute(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Hello World"); }); executor.shutdown(); System.out.println(executor.awaitTermination(3, TimeUnit.SECONDS)); // true
-
此种情况,任务执行完毕时间大于超时时间,即尚有线程未执行完毕,返回 false
executor.execute(() -> { try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Hello World"); }); executor.shutdown(); System.out.println(executor.awaitTermination(3, TimeUnit.SECONDS)); // false
-
-