Skip to content

Commit cee5115

Browse files
committed
add ThreadPool Utils
1 parent 66054bc commit cee5115

16 files changed

Lines changed: 571 additions & 7 deletions

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,18 @@
2121

2222
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2323
hs_err_pid*
24+
25+
# Eclipse
26+
.classpath
27+
.project
28+
target
29+
.settings
30+
31+
# Idea
32+
.idea
33+
*.iml
34+
35+
# git
36+
*.orig
37+
38+
*.zip

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# java-lib
1+
# baishi-common
22
Java通用代码仓库
33

44
## 目标

pom.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>io.baishi</groupId>
8+
<artifactId>baishi-common</artifactId>
9+
<version>1.0.0</version>
10+
11+
<properties>
12+
<maven.compiler.source>11</maven.compiler.source>
13+
<maven.compiler.target>11</maven.compiler.target>
14+
</properties>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>org.slf4j</groupId>
19+
<artifactId>slf4j-api</artifactId>
20+
<version>1.7.36</version>
21+
</dependency>
22+
<dependency>
23+
<groupId>org.apache.httpcomponents</groupId>
24+
<artifactId>httpclient</artifactId>
25+
<version>4.5.13</version>
26+
</dependency>
27+
<dependency>
28+
<groupId>org.apache.httpcomponents</groupId>
29+
<artifactId>httpcore</artifactId>
30+
<version>4.4.15</version>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.apache.commons</groupId>
34+
<artifactId>commons-lang3</artifactId>
35+
<version>3.12.0</version>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.apache.commons</groupId>
39+
<artifactId>commons-collections4</artifactId>
40+
<version>4.4</version>
41+
</dependency>
42+
</dependencies>
43+
44+
</project>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.baishi.common;
2+
3+
import java.io.IOException;
4+
import java.io.InputStreamReader;
5+
import java.util.Objects;
6+
import java.util.Properties;
7+
8+
/**
9+
* @author baishi
10+
* @date 2022/6/10 09:34
11+
*/
12+
public class PropertiesUtils {
13+
14+
/**
15+
* 根据clazz的物理路径,获取propertyFileName名称的属性文件的Properties对象
16+
*
17+
* @param clazz
18+
* @param propertyFileName
19+
* @return
20+
*/
21+
public static Properties getPropertyFile(Class clazz, String propertyFileName) throws IOException {
22+
InputStreamReader reader = new InputStreamReader(
23+
Objects.requireNonNull(
24+
clazz.getClassLoader().getResourceAsStream(propertyFileName)));
25+
26+
Properties p = new Properties();
27+
p.load(reader);
28+
29+
return p;
30+
}
31+
32+
/**
33+
* 默认路径
34+
*
35+
* @param key
36+
* @return
37+
*/
38+
public static String getValue(String key) {
39+
return getValue("classpath:META-INF/config.properties", key);
40+
}
41+
42+
/**
43+
* 指定路径
44+
*
45+
* @param fileName
46+
* @param key
47+
* @return
48+
*/
49+
public static String getValue(String fileName, String key) {
50+
try {
51+
Properties prop = getPropertyFile(PropertiesUtils.class, fileName);
52+
return prop.getProperty(key);
53+
} catch (IOException e) {
54+
return null;
55+
}
56+
}
57+
}

CustomHttpException.java renamed to src/main/java/io/baishi/common/http/CustomHttpException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.nick.common.exception;
1+
package io.baishi.common.http;
22

33
/**
44
* 自定义HTTP访问异常

HttpClient.java renamed to src/main/java/io/baishi/common/http/HttpClientUtils.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
package com.nick.common.http;
1+
package io.baishi.common.http;
22

3-
import com.nick.common.exception.CustomHttpException;
43
import org.apache.commons.lang3.StringUtils;
54
import org.apache.http.HttpEntity;
65
import org.apache.http.client.config.RequestConfig;
@@ -19,11 +18,11 @@
1918
* @author nick
2019
* @date 2018/2/24
2120
*/
22-
public class HttpClient {
21+
public class HttpClientUtils {
2322

2423
private static final int HTTP_STATUS_CODE_SUCCESS = 200;
2524

26-
private static CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
25+
private static final CloseableHttpClient CLOSEABLE_HTTP_CLIENT = HttpClients.createDefault();
2726

2827
private static final int CONNECTION_REQUEST_TIMEOUT = 1000;
2928
private static final int SOCKET_TIMEOUT = 1000;
@@ -121,7 +120,7 @@ public static byte[] sendPost(String url,
121120
.setConnectTimeout(connectTimeout)
122121
.build();
123122
httpPost.setConfig(requestConfig);
124-
try (CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpPost)) {
123+
try (CloseableHttpResponse httpResponse = CLOSEABLE_HTTP_CLIENT.execute(httpPost)) {
125124
if (httpResponse.getStatusLine().getStatusCode() != HTTP_STATUS_CODE_SUCCESS) {
126125
throw new CustomHttpException(httpResponse.getStatusLine() + ". url is " + url);
127126
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package io.baishi.common.thread.threadpool;
2+
3+
import java.util.concurrent.*;
4+
5+
/**
6+
* 线程池构造参数有8个,但是最核心的是3个:corePoolSize、maximumPoolSize,workQueue,
7+
* 它们最大程度地决定了线程池的任务分配和线程分配策略。
8+
* <p>
9+
* <p>1. 并行执行子任务,提高响应速度。</p>
10+
* <p>>>>>这种情况下,应该使用同步队列,没有什么任务应该被缓存下来,而是应该立即执行。</p>
11+
* <p>2. 并行执行大批次任务,提升吞吐量。</p>
12+
* <p>>>>>这种情况下,应该使用有界队列,使用队列去缓冲大批量的任务,队列容量必须声明,防止任务无限制堆积。</p>
13+
*
14+
* @author baishi
15+
* @date 2022/1/18 15:08
16+
*/
17+
public abstract class AbstractThreadPoolBuilder {
18+
19+
/**
20+
* 默认拒绝策略
21+
*/
22+
protected static final RejectedExecutionHandler DEFAULT_REJECT_HANDLER = new ThreadPoolExecutor.AbortPolicy();
23+
24+
/**
25+
* CPU 核心数量
26+
*/
27+
protected static final int CPU_COUNT = MachineUtils.getCpuCount();
28+
29+
protected ThreadFactory threadFactory;
30+
31+
protected RejectedExecutionHandler rejectedExecutionHandler;
32+
33+
/**
34+
* 任务队列大小
35+
* <p>
36+
* 默认为-1,表示不限制大小,使用{@link LinkedBlockingDeque}存储
37+
*/
38+
protected int queueSize = -1;
39+
40+
protected int maximumPoolSize = CPU_COUNT;
41+
42+
protected int keepAliveTimeMilliSeconds = 1000;
43+
44+
protected boolean daemon = false;
45+
46+
protected String threadNamePrefix;
47+
48+
/**
49+
* 最大线程数
50+
*
51+
* @return
52+
*/
53+
protected int getMaximumPoolSize(int coreSize) {
54+
return Math.max(coreSize, maximumPoolSize);
55+
}
56+
57+
protected BlockingQueue<Runnable> getBlockingQueue() {
58+
return queueSize < 1 ?
59+
new LinkedBlockingDeque<>() :
60+
new ArrayBlockingQueue<>(queueSize);
61+
}
62+
63+
protected RejectedExecutionHandler getRejectedExecutionHandler() {
64+
65+
if (rejectedExecutionHandler == null) {
66+
rejectedExecutionHandler = DEFAULT_REJECT_HANDLER;
67+
}
68+
69+
return rejectedExecutionHandler;
70+
}
71+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package io.baishi.common.thread.threadpool;
2+
3+
import io.baishi.common.thread.threadpool.dynamic.DynamicThreadPoolExecutor;
4+
5+
import java.util.concurrent.RejectedExecutionHandler;
6+
import java.util.concurrent.ThreadFactory;
7+
import java.util.concurrent.TimeUnit;
8+
9+
/**
10+
* 处理CPU密集的线程池
11+
* <p>
12+
* 最佳线程数 = CPU核数 + 1
13+
*
14+
* @author baishi
15+
* @date 2022/1/17 14:48
16+
*/
17+
public class CpuThreadPoolBuilder extends AbstractThreadPoolBuilder {
18+
19+
/**
20+
* 计算核心线程数量
21+
*
22+
* @return
23+
*/
24+
public int getCorePoolSize() {
25+
return CPU_COUNT + 1;
26+
}
27+
28+
public CpuThreadPoolBuilder setThreadFactory(ThreadFactory threadFactory) {
29+
this.threadFactory = threadFactory;
30+
return this;
31+
}
32+
33+
public CpuThreadPoolBuilder setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
34+
this.rejectedExecutionHandler = rejectedExecutionHandler;
35+
return this;
36+
}
37+
38+
public CpuThreadPoolBuilder setQueueSize(int queueSize) {
39+
this.queueSize = queueSize;
40+
return this;
41+
}
42+
43+
public CpuThreadPoolBuilder setMaximumPoolSize(int maximumPoolSize) {
44+
this.maximumPoolSize = maximumPoolSize;
45+
return this;
46+
}
47+
48+
public CpuThreadPoolBuilder setKeepAliveTimeMilliSeconds(int keepAliveTimeMilliSeconds) {
49+
this.keepAliveTimeMilliSeconds = keepAliveTimeMilliSeconds;
50+
return this;
51+
}
52+
53+
public CpuThreadPoolBuilder setDaemon(boolean daemon) {
54+
this.daemon = daemon;
55+
return this;
56+
}
57+
58+
public CpuThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
59+
this.threadNamePrefix = threadNamePrefix;
60+
return this;
61+
}
62+
63+
public DynamicThreadPoolExecutor builder() {
64+
65+
threadFactory = ThreadPoolUtils.createThreadFactory(this.threadNamePrefix, this.daemon);
66+
67+
return new DynamicThreadPoolExecutor(
68+
getCorePoolSize(),
69+
getMaximumPoolSize(getCorePoolSize()),
70+
keepAliveTimeMilliSeconds,
71+
TimeUnit.MILLISECONDS,
72+
getBlockingQueue(),
73+
threadFactory,
74+
getRejectedExecutionHandler());
75+
}
76+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package io.baishi.common.thread.threadpool;
2+
3+
import io.baishi.common.thread.threadpool.dynamic.DynamicThreadPoolExecutor;
4+
5+
import java.util.concurrent.RejectedExecutionHandler;
6+
import java.util.concurrent.ThreadFactory;
7+
import java.util.concurrent.TimeUnit;
8+
9+
/**
10+
* 处理IO密集的线程池
11+
* <p>
12+
* 最佳线程数 = CPU核数 * [ 1 +(I/O 耗时 / CPU 耗时)]
13+
*
14+
* @author baishi
15+
* @date 2022/1/17 14:50
16+
*/
17+
public class IoThreadPoolBuilder extends AbstractThreadPoolBuilder {
18+
19+
/**
20+
* 计算核心线程数量
21+
*
22+
* @param ioTime
23+
* @param cpuTime
24+
* @return
25+
*/
26+
public int getCorePoolSize(int ioTime, int cpuTime) {
27+
return CPU_COUNT + (1 + (ioTime / cpuTime));
28+
}
29+
30+
public IoThreadPoolBuilder setThreadFactory(ThreadFactory threadFactory) {
31+
this.threadFactory = threadFactory;
32+
return this;
33+
}
34+
35+
public IoThreadPoolBuilder setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
36+
this.rejectedExecutionHandler = rejectedExecutionHandler;
37+
return this;
38+
}
39+
40+
public IoThreadPoolBuilder setQueueSize(int queueSize) {
41+
this.queueSize = queueSize;
42+
return this;
43+
}
44+
45+
public IoThreadPoolBuilder setMaximumPoolSize(int maximumPoolSize) {
46+
this.maximumPoolSize = maximumPoolSize;
47+
return this;
48+
}
49+
50+
public IoThreadPoolBuilder setKeepAliveTimeMilliSeconds(int keepAliveTimeMilliSeconds) {
51+
this.keepAliveTimeMilliSeconds = keepAliveTimeMilliSeconds;
52+
return this;
53+
}
54+
55+
public IoThreadPoolBuilder setDaemon(boolean daemon) {
56+
this.daemon = daemon;
57+
return this;
58+
}
59+
60+
public IoThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
61+
this.threadNamePrefix = threadNamePrefix;
62+
return this;
63+
}
64+
65+
public DynamicThreadPoolExecutor builder(int ioTime, int cpuTime) {
66+
67+
threadFactory = ThreadPoolUtils.createThreadFactory(this.threadNamePrefix, this.daemon);
68+
69+
return new DynamicThreadPoolExecutor(
70+
getCorePoolSize(ioTime, cpuTime),
71+
getMaximumPoolSize(getCorePoolSize(ioTime, cpuTime)),
72+
keepAliveTimeMilliSeconds,
73+
TimeUnit.MILLISECONDS,
74+
getBlockingQueue(),
75+
threadFactory,
76+
getRejectedExecutionHandler());
77+
}
78+
}

0 commit comments

Comments
 (0)