This commit is contained in:
Looly 2023-06-28 16:22:50 +08:00
parent edc08cf1de
commit e8adf37407
3 changed files with 86 additions and 54 deletions

View File

@ -15,16 +15,7 @@ package org.dromara.hutool.core.thread;
import org.dromara.hutool.core.lang.builder.Builder;
import org.dromara.hutool.core.util.ObjUtil;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
/**
* {@link ThreadPoolExecutor} 建造者
@ -42,8 +33,10 @@ import java.util.concurrent.TimeUnit;
public class ExecutorBuilder implements Builder<ThreadPoolExecutor> {
private static final long serialVersionUID = 1L;
/** 默认的等待队列容量 */
public static final int DEFAULT_QUEUE_CAPACITY = 1024;
/**
* 默认的等待队列容量
*/
public static final int DEFAULT_QUEUE_CAPACITY = Integer.MAX_VALUE;
/**
* 初始池大小
@ -137,6 +130,18 @@ public class ExecutorBuilder implements Builder<ThreadPoolExecutor> {
return this;
}
/**
* 使用{@link LinkedBlockingQueue} 作为等待队列<br>
* 队列满时运行线程小于maxPoolSize时会创建新线程否则触发异常策略
*
* @param capacity 队列容量
* @return this
* @since 6.0.0
*/
public ExecutorBuilder useLinkedBlockingQueue(final int capacity) {
return setWorkQueue(new LinkedBlockingQueue<>(capacity));
}
/**
* 使用{@link ArrayBlockingQueue} 做为等待队列<br>
* 有界队列相对无界队列有利于控制队列大小队列满时运行线程小于maxPoolSize时会创建新线程否则触发异常策略
@ -257,12 +262,12 @@ public class ExecutorBuilder implements Builder<ThreadPoolExecutor> {
final RejectedExecutionHandler handler = ObjUtil.defaultIfNull(builder.handler, RejectPolicy.ABORT.getValue());
final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(//
corePoolSize, //
maxPoolSize, //
keepAliveTime, TimeUnit.NANOSECONDS, //
workQueue, //
threadFactory, //
handler//
corePoolSize, //
maxPoolSize, //
keepAliveTime, TimeUnit.NANOSECONDS, //
workQueue, //
threadFactory, //
handler//
);
if (null != builder.allowCoreThreadTimeOut) {
threadPoolExecutor.allowCoreThreadTimeOut(builder.allowCoreThreadTimeOut);

View File

@ -39,25 +39,6 @@ import java.util.function.Supplier;
*/
public class ThreadUtil {
/**
* 新建一个线程池默认的策略如下
* <pre>
* 1. 初始线程数为corePoolSize指定的大小
* 2. 没有最大线程数限制
* 3. 默认使用LinkedBlockingQueue默认队列大小为1024
* </pre>
*
* @param corePoolSize 同时执行的线程数大小
* @return ExecutorService
*/
public static ExecutorService newExecutor(final int corePoolSize) {
final ExecutorBuilder builder = ExecutorBuilder.of();
if (corePoolSize > 0) {
builder.setCorePoolSize(corePoolSize);
}
return builder.build();
}
/**
* 获得一个新的线程池默认的策略如下
* <pre>
@ -86,10 +67,25 @@ public class ThreadUtil {
*/
public static ExecutorService newSingleExecutor() {
return ExecutorBuilder.of()//
.setCorePoolSize(1)//
.setMaxPoolSize(1)//
.setKeepAliveTime(0)//
.buildFinalizable();
.setCorePoolSize(1)//
.setMaxPoolSize(1)//
.setKeepAliveTime(0)//
.buildFinalizable();
}
/**
* 新建一个线程池默认的策略如下
* <pre>
* 1. 初始线程数为poolSize指定的大小
* 2. 最大线程数为poolSize指定的大小
* 3. 默认使用LinkedBlockingQueue默认无界队列
* </pre>
*
* @param poolSize 同时执行的线程数大小
* @return ExecutorService
*/
public static ExecutorService newExecutor(final int poolSize) {
return newExecutor(poolSize, poolSize);
}
/**
@ -102,9 +98,9 @@ public class ThreadUtil {
*/
public static ThreadPoolExecutor newExecutor(final int corePoolSize, final int maximumPoolSize) {
return ExecutorBuilder.of()
.setCorePoolSize(corePoolSize)
.setMaxPoolSize(maximumPoolSize)
.build();
.setCorePoolSize(corePoolSize)
.setMaxPoolSize(maximumPoolSize)
.build();
}
/**
@ -119,10 +115,10 @@ public class ThreadUtil {
*/
public static ExecutorService newExecutor(final int corePoolSize, final int maximumPoolSize, final int maximumQueueSize) {
return ExecutorBuilder.of()
.setCorePoolSize(corePoolSize)
.setMaxPoolSize(maximumPoolSize)
.setWorkQueue(new LinkedBlockingQueue<>(maximumQueueSize))
.build();
.setCorePoolSize(corePoolSize)
.setMaxPoolSize(maximumPoolSize)
.useLinkedBlockingQueue(maximumQueueSize)
.build();
}
/**
@ -184,7 +180,7 @@ public class ThreadUtil {
*/
public static ExecutorService newFixedExecutor(final int nThreads, final int maximumQueueSize, final String threadNamePrefix, final boolean isBlocked) {
return newFixedExecutor(nThreads, maximumQueueSize, threadNamePrefix,
(isBlocked ? RejectPolicy.BLOCK : RejectPolicy.ABORT).getValue());
(isBlocked ? RejectPolicy.BLOCK : RejectPolicy.ABORT).getValue());
}
/**
@ -207,11 +203,11 @@ public class ThreadUtil {
final String threadNamePrefix,
final RejectedExecutionHandler handler) {
return ExecutorBuilder.of()
.setCorePoolSize(nThreads).setMaxPoolSize(nThreads)
.setWorkQueue(new LinkedBlockingQueue<>(maximumQueueSize))
.setThreadFactory(createThreadFactory(threadNamePrefix))
.setHandler(handler)
.build();
.setCorePoolSize(nThreads).setMaxPoolSize(nThreads)
.setWorkQueue(new LinkedBlockingQueue<>(maximumQueueSize))
.setThreadFactory(createThreadFactory(threadNamePrefix))
.setHandler(handler)
.build();
}
/**

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.thread;
import org.dromara.hutool.core.lang.Console;
import java.util.concurrent.ExecutorService;
public class Issue3167Test {
public static void main(final String[] args) {
final ExecutorService executorService = ThreadUtil.newExecutor(2);
for (int i = 0; i < 1035; i++) {
final int finalI = i;
executorService.submit(() -> {
Console.log(Thread.currentThread().getName(), finalI);
ThreadUtil.sleep(5000);
});
}
}
}