Package org.miaixz.bus.core.xyz
Class ThreadKit
java.lang.Object
org.miaixz.bus.core.xyz.ThreadKit
线程池工具
- Since:
- Java 17+
- Author:
- Kimi Liu
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic ConcurrencyTesterconcurrencyTest(int threadSize, Runnable runnable) 并发测试 此方法用于测试多线程下执行某些逻辑的并发性能 调用此方法会导致当前线程阻塞。 结束后可调用ConcurrencyTester.getInterval()方法获取执行时间static ScheduledThreadPoolExecutorcreateScheduledExecutor(int corePoolSize) static ThreadFactorycreateThreadFactory(String threadNamePrefix) 创建自定义线程名称前缀的ThreadFactorystatic ThreadFactoryBuilder创建ThreadFactoryBuilderstatic <T> ThreadLocal<T> createThreadLocal(boolean isInheritable) 创建本地线程对象static <T> ThreadLocal<T> createThreadLocal(Supplier<? extends T> supplier) 创建本地线程对象static ThreadGroup获取当前线程的线程组static long获取当前线程ID,即TIDstatic Future<?> 执行有返回值的异步方法 Future代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞static Runnable执行异步方法static <T> Future<T> 执行有返回值的异步方法 Future代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞static void直接在公共线程池中执行线程static Thread获取进程的主线程static StackTraceElement[]static StackTraceElementgetStackTraceElement(int i) 获得堆栈项static Thread[]获取JVM中与当前线程同组的所有线程static Thread[]getThreads(ThreadGroup group) 获取JVM中与当前线程同组的所有线程 使用数组二次拷贝方式,防止在线程列表获取过程中线程终止static void结束线程,调用此方法后,线程将抛出InterruptedException异常static <T> CompletionService<T> 新建一个CompletionService,调用其submit方法可以异步执行多个任务,最后调用take方法按照完成的顺序获得其结果。 若未完成,则会阻塞static <T> CompletionService<T> newCompletionService(ExecutorService executor) 新建一个CompletionService,调用其submit方法可以异步执行多个任务,最后调用take方法按照完成的顺序获得其结果。 若未完成,则会阻塞static CountDownLatchnewCountDownLatch(int taskCount) 新建一个CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 示例:等6个同学都离开教室,班长才能锁门。static CyclicBarriernewCyclicBarrier(int taskCount) 新建一个CycleBarrier 循环栅栏,一个同步辅助类 示例:7个同学,集齐7个龙珠,7个同学一起召唤神龙;前后集齐了2次static ExecutorService获得一个新的线程池,默认的策略如下:static ThreadPoolExecutornewExecutor(int poolSize) 新建一个线程池,默认的策略如下:static ThreadPoolExecutornewExecutor(int corePoolSize, int maximumPoolSize) 获得一个新的线程池 如果maximumPoolSize >= corePoolSize,在没有新任务加入的情况下,多出的线程将最多保留60sstatic ExecutorServicenewExecutor(int corePoolSize, int maximumPoolSize, int maximumQueueSize) 获得一个新的线程池,并指定最大任务队列大小 如果maximumPoolSize >= corePoolSize,在没有新任务加入的情况下,多出的线程将最多保留60sstatic ThreadPoolExecutornewExecutorByBlockingCoefficient(float blockingCoefficient) 获得一个新的线程池 传入阻塞系数,线程池的大小计算公式为:CPU可用核心数 / (1 - 阻塞因子) Blocking Coefficient(阻塞系数) = 阻塞时间/(阻塞时间+使用CPU的时间) 计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近于1。static ThreadPoolExecutornewFixedExecutor(int nThreads, int maximumQueueSize, String threadNamePrefix, boolean isBlocked) 获取一个新的线程池,默认的策略如下static ThreadPoolExecutornewFixedExecutor(int nThreads, int maximumQueueSize, String threadNamePrefix, RejectedExecutionHandler handler) 获得一个新的线程池,默认策略如下static ExecutorServicenewFixedExecutor(int nThreads, String threadNamePrefix, boolean isBlocked) 获取一个新的线程池,默认的策略如下static ThreadFactorynewNamedThreadFactory(String prefix, boolean isDaemon) 创建线程工厂static ThreadFactorynewNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon) 创建线程工厂static ThreadFactorynewNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon, Thread.UncaughtExceptionHandler handler) 创建线程工厂static PhasernewPhaser(int taskCount) 新建一个Phaser,一个同步辅助类,jdk1.7提供,可以完全替代CountDownLatch; Pharser: 移相器、相位器,可重用同步屏障; 功能可以替换:CyclicBarrier(固定线程)循环栅栏、CountDownLatch(固定计数)倒数计数、加上分层功能 示例1:等6个同学都离开教室,班长才能锁门。static ExecutorService获得一个新的线程池,只有单个线程,策略如下:static Thread创建新线程,非守护线程,正常优先级,线程组与当前线程的线程组一致static Thread创建新线程static booleansafeSleep(long millis) 考虑Thread.sleep(long)方法有可能时间不足给定毫秒数,此方法保证sleep时间不小于给定的毫秒数static boolean考虑Thread.sleep(long)方法有可能时间不足给定毫秒数,此方法保证sleep时间不小于给定的毫秒数static ScheduledExecutorServiceschedule(ScheduledExecutorService executor, Runnable command, long initialDelay, long period, boolean fixedRateOrFixedDelay) 开始执行一个定时任务,执行方式分fixedRate模式和fixedDelay模式。 注意:此方法的延迟和周期的单位均为毫秒。 fixedRate 模式:以固定的频率执行。每period的时刻检查,如果上个任务完成,启动下个任务,否则等待上个任务结束后立即启动。 fixedDelay模式:以固定的延时执行。上次任务结束后等待period再执行下个任务。static ScheduledExecutorServiceschedule(ScheduledExecutorService executor, Runnable command, long initialDelay, long period, TimeUnit timeUnit, boolean fixedRateOrFixedDelay) 开始执行一个定时任务,执行方式分fixedRate模式和fixedDelay模式。 fixedRate 模式:以固定的频率执行。每period的时刻检查,如果上个任务完成,启动下个任务,否则等待上个任务结束后立即启动。 fixedDelay模式:以固定的延时执行。上次任务结束后等待period再执行下个任务。static booleansleep(long millis) 挂起当前线程static boolean挂起当前线程static boolean挂起当前线程static void阻塞当前线程,保证在main方法中执行不被退出static void等待当前线程结束.static voidwaitForDie(Thread thread) 等待线程结束.
-
Constructor Details
-
ThreadKit
public ThreadKit()
-
-
Method Details
-
newExecutor
获得一个新的线程池,默认的策略如下:1. 初始线程数为 0 2. 最大线程数为Integer.MAX_VALUE 3. 使用SynchronousQueue 4. 任务直接提交给线程而不保持它们- Returns:
ExecutorService
-
newSingleExecutor
获得一个新的线程池,只有单个线程,策略如下:1. 初始线程数为 1 2. 最大线程数为 1 3. 默认使用LinkedBlockingQueue,默认队列大小为1024 4. 同时只允许一个线程工作,剩余放入队列等待,等待数超过1024报错- Returns:
ExecutorService
-
newExecutor
新建一个线程池,默认的策略如下:1. 初始线程数为poolSize指定的大小 2. 最大线程数为poolSize指定的大小 3. 默认使用LinkedBlockingQueue,默认无界队列- Parameters:
poolSize- 同时执行的线程数大小- Returns:
ThreadPoolExecutor
-
newExecutor
获得一个新的线程池 如果maximumPoolSize >= corePoolSize,在没有新任务加入的情况下,多出的线程将最多保留60s- Parameters:
corePoolSize- 初始线程池大小maximumPoolSize- 最大线程池大小- Returns:
ThreadPoolExecutor
-
newExecutor
public static ExecutorService newExecutor(int corePoolSize, int maximumPoolSize, int maximumQueueSize) 获得一个新的线程池,并指定最大任务队列大小 如果maximumPoolSize >= corePoolSize,在没有新任务加入的情况下,多出的线程将最多保留60s- Parameters:
corePoolSize- 初始线程池大小maximumPoolSize- 最大线程池大小maximumQueueSize- 最大任务队列大小- Returns:
ThreadPoolExecutor
-
newExecutorByBlockingCoefficient
获得一个新的线程池 传入阻塞系数,线程池的大小计算公式为:CPU可用核心数 / (1 - 阻塞因子) Blocking Coefficient(阻塞系数) = 阻塞时间/(阻塞时间+使用CPU的时间) 计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近于1。see: http://blog.csdn.net/partner4java/article/details/9417663
- Parameters:
blockingCoefficient- 阻塞系数,阻塞因子介于0~1之间的数,阻塞因子越大,线程池中的线程数越多。- Returns:
ThreadPoolExecutor
-
newFixedExecutor
public static ExecutorService newFixedExecutor(int nThreads, String threadNamePrefix, boolean isBlocked) 获取一个新的线程池,默认的策略如下1. 核心线程数与最大线程数为nThreads指定的大小 2. 默认使用LinkedBlockingQueue,默认队列大小为1024 3. 如果isBlocked为true,当执行拒绝策略的时候会处于阻塞状态,直到能添加到队列中或者被Thread.interrupt()中断- Parameters:
nThreads- 线程池大小threadNamePrefix- 线程名称前缀isBlocked- 是否使用BlockPolicy策略- Returns:
ExecutorService
-
newFixedExecutor
public static ThreadPoolExecutor newFixedExecutor(int nThreads, int maximumQueueSize, String threadNamePrefix, boolean isBlocked) 获取一个新的线程池,默认的策略如下1. 核心线程数与最大线程数为nThreads指定的大小 2. 默认使用LinkedBlockingQueue 3. 如果isBlocked为true,当执行拒绝策略的时候会处于阻塞状态,直到能添加到队列中或者被Thread.interrupt()中断- Parameters:
nThreads- 线程池大小maximumQueueSize- 队列大小threadNamePrefix- 线程名称前缀isBlocked- 是否使用BlockPolicy策略- Returns:
ThreadPoolExecutor
-
newFixedExecutor
public static ThreadPoolExecutor newFixedExecutor(int nThreads, int maximumQueueSize, String threadNamePrefix, RejectedExecutionHandler handler) 获得一个新的线程池,默认策略如下1. 核心线程数与最大线程数为nThreads指定的大小 2. 默认使用LinkedBlockingQueue- Parameters:
nThreads- 线程池大小maximumQueueSize- 队列大小threadNamePrefix- 线程名称前缀handler- 拒绝策略- Returns:
ThreadPoolExecutor
-
execute
直接在公共线程池中执行线程- Parameters:
runnable- 可运行对象
-
execAsync
执行异步方法- Parameters:
runnable- 需要执行的方法体isDaemon- 是否守护线程。守护线程会在主线程结束后自动结束- Returns:
- 执行的方法体
-
execAsync
执行有返回值的异步方法 Future代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞 -
execAsync
执行有返回值的异步方法 Future代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞- Parameters:
runnable- 可运行对象- Returns:
Future
-
newCompletionService
新建一个CompletionService,调用其submit方法可以异步执行多个任务,最后调用take方法按照完成的顺序获得其结果。 若未完成,则会阻塞- Type Parameters:
T- 回调对象类型- Returns:
CompletionService
-
newCompletionService
新建一个CompletionService,调用其submit方法可以异步执行多个任务,最后调用take方法按照完成的顺序获得其结果。 若未完成,则会阻塞- Type Parameters:
T- 回调对象类型- Parameters:
executor- 执行器ExecutorService- Returns:
CompletionService
-
newCountDownLatch
新建一个CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 示例:等6个同学都离开教室,班长才能锁门。
该示例,也可以用:CountDownLatch latch = new CountDownLatch(6); // 总共任务是6 for (int x = 0; x < 6; x++) { //具体生产任务,可以用线程池替换 new Thread(()->{ try { //每个同学在教室待上几秒秒钟 int time = ThreadLocalRandom.current().nextInt(1, 5); TimeUnit.SECONDS.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("同学【%s】,已经离开了教室%n", Thread.currentThread().getName()); latch.countDown(); // 减1(每离开一个同学,减去1),必须执行,可以放到 try...finally中 },"同学 - " + x).start(); } latch.await(); // 等待计数为0后再解除阻塞;(等待所有同学离开) System.out.println("【主线程】所有同学都离开了教室,开始锁教室大门了。");Phaser移相器 进行实现- Parameters:
taskCount- 任务数量- Returns:
CountDownLatch
-
newCyclicBarrier
新建一个CycleBarrier 循环栅栏,一个同步辅助类 示例:7个同学,集齐7个龙珠,7个同学一起召唤神龙;前后集齐了2次
该示例,也可以用:AtomicInteger times = new AtomicInteger(); CyclicBarrier barrier = new CyclicBarrier(7, ()->{ System.out.println(""); System.out.println(""); System.out.println("【循环栅栏业务处理】7个子线程 都收集了一颗龙珠,七颗龙珠已经收集齐全,开始召唤神龙。" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); times.getAndIncrement(); }); // 现在设置的栅栏的数量为2 for (int x = 0; x < 7; x++) { // 创建7个线程, 当然也可以使用线程池替换。 new Thread(() -> { while (times.get() < 2) { try { System.out.printf("【Barrier - 收集龙珠】当前的线程名称:%s%n", Thread.currentThread().getName()); int time = ThreadLocalRandom.current().nextInt(1, 10); // 等待一段时间,模拟线程的执行时间 TimeUnit.SECONDS.sleep(time); // 模拟业务延迟,收集龙珠的时间 barrier.await(); // 等待,凑够了7个等待的线程 System.err.printf("〖Barrier - 举起龙珠召唤神龙〗当前的线程名称:%s\t%s%n", Thread.currentThread().getName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); if (barrier.getParties() >= 7) { barrier.reset(); // 重置栅栏,等待下一次的召唤。 } } catch (Exception e) { e.printStackTrace(); } } }, "线程 - " + x).start(); }Phaser移相器 进行实现- Parameters:
taskCount- 任务数量- Returns:
CyclicBarrier
-
newPhaser
新建一个Phaser,一个同步辅助类,jdk1.7提供,可以完全替代CountDownLatch; Pharser: 移相器、相位器,可重用同步屏障; 功能可以替换:CyclicBarrier(固定线程)循环栅栏、CountDownLatch(固定计数)倒数计数、加上分层功能 示例1:等6个同学都离开教室,班长才能锁门。
示例2:7个同学,集齐7个龙珠,7个同学一起召唤神龙; 只需要:phaser.arrive(); --> phaser.arriveAndAwaitAdvance() //等待其他的线程就位 该示例,也可以用:Phaser phaser = new Phaser(6); // 总共任务是6 for (int x = 0; x < 6; x++) { //具体生产任务,可以用线程池替换 new Thread(()->{ try { //每个同学在教室待上几秒秒钟 int time = ThreadLocalRandom.current().nextInt(1, 5); TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("同学【%s】,已经离开了教室%n", Thread.currentThread().getName()); phaser.arrive(); // 减1 等价于countDown()方法(每离开一个同学,减去1),必须执行,可以放到 try...finally中 },"同学 - " + x).start(); } phaser.awaitAdvance(phaser.getPhase()); // 等价于latch.await()方法 等待计数为0后再解除阻塞;(等待所有同学离开) System.out.println("【主线程】所有同学都离开了教室,开始锁教室大门了。");CyclicBarrier进行实现- Parameters:
taskCount- 任务数量- Returns:
Phaser
-
newThread
创建新线程,非守护线程,正常优先级,线程组与当前线程的线程组一致 -
newThread
创建新线程 -
sleep
挂起当前线程- Parameters:
timeout- 挂起的时长timeUnit- 时长单位- Returns:
- 被中断返回false,否则true
-
sleep
挂起当前线程- Parameters:
millis- 挂起的毫秒数- Returns:
- 被中断返回false,否则true
-
sleep
public static boolean sleep(long millis) 挂起当前线程- Parameters:
millis- 挂起的毫秒数- Returns:
- 被中断返回false,否则true
-
safeSleep
考虑Thread.sleep(long)方法有可能时间不足给定毫秒数,此方法保证sleep时间不小于给定的毫秒数- Parameters:
millis- 给定的sleep时间- Returns:
- 被中断返回false,否则true
- See Also:
-
safeSleep
public static boolean safeSleep(long millis) 考虑Thread.sleep(long)方法有可能时间不足给定毫秒数,此方法保证sleep时间不小于给定的毫秒数- Parameters:
millis- 给定的sleep时间(毫秒)- Returns:
- 被中断返回false,否则true
- See Also:
-
getStackTrace
- Returns:
- 获得堆栈列表
-
getStackTraceElement
获得堆栈项- Parameters:
i- 第几个堆栈项- Returns:
- 堆栈项
-
createThreadLocal
创建本地线程对象- Type Parameters:
T- 持有对象类型- Parameters:
isInheritable- 是否为子线程提供从父线程那里继承的值- Returns:
- 本地线程
-
createThreadLocal
创建本地线程对象- Type Parameters:
T- 持有对象类型- Parameters:
supplier- 初始化线程对象函数- Returns:
- 本地线程
- See Also:
-
createThreadFactoryBuilder
创建ThreadFactoryBuilder- Returns:
- ThreadFactoryBuilder
- See Also:
-
createThreadFactory
创建自定义线程名称前缀的ThreadFactory- Parameters:
threadNamePrefix- 线程名称前缀- Returns:
ThreadFactory- See Also:
-
interrupt
结束线程,调用此方法后,线程将抛出InterruptedException异常- Parameters:
thread- 线程isJoin- 是否等待结束
-
waitForDie
public static void waitForDie()等待当前线程结束. 调用Thread.join()并忽略InterruptedException -
waitForDie
等待线程结束. 调用Thread.join()并忽略InterruptedException- Parameters:
thread- 线程
-
getThreads
获取JVM中与当前线程同组的所有线程- Returns:
- 线程对象数组
-
getThreads
获取JVM中与当前线程同组的所有线程 使用数组二次拷贝方式,防止在线程列表获取过程中线程终止- Parameters:
group- 线程组- Returns:
- 线程对象数组
-
getMainThread
获取进程的主线程- Returns:
- 进程的主线程
-
currentThreadGroup
获取当前线程的线程组- Returns:
- 线程组
-
currentThreadId
public static long currentThreadId()获取当前线程ID,即TID- Returns:
- TID
-
newNamedThreadFactory
创建线程工厂- Parameters:
prefix- 线程名前缀isDaemon- 是否守护线程- Returns:
ThreadFactory
-
newNamedThreadFactory
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon) 创建线程工厂- Parameters:
prefix- 线程名前缀threadGroup- 线程组,可以为nullisDaemon- 是否守护线程- Returns:
ThreadFactory
-
newNamedThreadFactory
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon, Thread.UncaughtExceptionHandler handler) 创建线程工厂- Parameters:
prefix- 线程名前缀threadGroup- 线程组,可以为nullisDaemon- 是否守护线程handler- 未捕获异常处理- Returns:
ThreadFactory
-
sync
阻塞当前线程,保证在main方法中执行不被退出- Parameters:
obj- 对象所在线程
-
concurrencyTest
并发测试 此方法用于测试多线程下执行某些逻辑的并发性能 调用此方法会导致当前线程阻塞。 结束后可调用ConcurrencyTester.getInterval()方法获取执行时间- Parameters:
threadSize- 并发线程数runnable- 执行的逻辑实现- Returns:
ConcurrencyTester
-
createScheduledExecutor
- Parameters:
corePoolSize- 初始线程池大小- Returns:
ScheduledThreadPoolExecutor
-
schedule
public static ScheduledExecutorService schedule(ScheduledExecutorService executor, Runnable command, long initialDelay, long period, boolean fixedRateOrFixedDelay) 开始执行一个定时任务,执行方式分fixedRate模式和fixedDelay模式。 注意:此方法的延迟和周期的单位均为毫秒。- fixedRate 模式:以固定的频率执行。每period的时刻检查,如果上个任务完成,启动下个任务,否则等待上个任务结束后立即启动。
- fixedDelay模式:以固定的延时执行。上次任务结束后等待period再执行下个任务。
- Parameters:
executor- 定时任务线程池,null新建一个默认线程池command- 需要定时执行的逻辑initialDelay- 初始延迟,单位毫秒period- 执行周期,单位毫秒fixedRateOrFixedDelay-true表示fixedRate模式,false表示fixedDelay模式- Returns:
ScheduledExecutorService
-
schedule
public static ScheduledExecutorService schedule(ScheduledExecutorService executor, Runnable command, long initialDelay, long period, TimeUnit timeUnit, boolean fixedRateOrFixedDelay) 开始执行一个定时任务,执行方式分fixedRate模式和fixedDelay模式。- fixedRate 模式:以固定的频率执行。每period的时刻检查,如果上个任务完成,启动下个任务,否则等待上个任务结束后立即启动。
- fixedDelay模式:以固定的延时执行。上次任务结束后等待period再执行下个任务。
- Parameters:
executor- 定时任务线程池,null新建一个默认线程池command- 需要定时执行的逻辑initialDelay- 初始延迟period- 执行周期timeUnit- 时间单位fixedRateOrFixedDelay-true表示fixedRate模式,false表示fixedDelay模式- Returns:
ScheduledExecutorService
-