ThreadPoolExecutor 动态调节线程池大小
调节corePoolSize和maximumPoolSIze
public class ThreadChangeMain {
public static void main(String[] args) throws InterruptedException {
dynamicThreadPoolExecutor();
}
private static void dynamicThreadPoolExecutor() throws InterruptedException {
ThreadPoolExecutor executor = buildThreadPool();
for (int i = 0; i < 50; i++) {
executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
new Thread(() -> {
while (true) {
threadStatus(executor, "线程统计");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
TimeUnit.SECONDS.sleep(10);
//threadStatus(executor, "改变之前");
//先设置maxPoolSize,不然会设置失败
//executor.setMaximumPoolSize(10);
//executor.setCorePoolSize(10);
//threadStatus(executor, "改变之后");
Thread.currentThread().join();
}
private static void threadStatus(ThreadPoolExecutor executor, String name) {
LinkedBlockingQueue queue = (LinkedBlockingQueue) executor.getQueue();
String format = MessageFormat.format(
"{9}-{0}-{1}-: " +
"核心数线程:{2}, " +
"最大线程数: {3}, " +
"队列大小: {4}, " +
"活动线程数: {5}, " +
"任务完成数: {6}, " +
"当前排队线程数: {7}," +
"队列剩余大小: {8} " +
"队列使用率: {10}",
Thread.currentThread().getName(), name,
executor.getCorePoolSize(),
executor.getMaximumPoolSize(),
(queue.size() + queue.remainingCapacity()),
executor.getActiveCount(),
executor.getCompletedTaskCount(),
queue.size(),
queue.remainingCapacity(),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()),
countPercentage(queue.size(), (queue.size() + queue.remainingCapacity()))
);
System.out.println(format);
}
public static String countPercentage(int up, int down){
return String.format("%1.2f%%", Double.parseDouble(up+"")/Double.parseDouble(down+"")*100);
}
private static ThreadPoolExecutor buildThreadPool() {
return new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(45));
}
}
执行结果:
放开注释代码:
threadStatus(executor, "改变之前");
//先设置maxPoolSize,不然会设置失败
executor.setMaximumPoolSize(10);
executor.setCorePoolSize(10);
threadStatus(executor, "改变之后");
可以发现核心数和最大线程数已经修改成功
修改任务队列长度
没有原始方法去设置队列长度,网上说 copy LinkedBlockingQueue, 修改capacity
public class ScalableLinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
private static final long serialVersionUID = -6903933977591709194L;
// 其他的和 LinkedBlockingQueue 一致
/**
* 修改 capacity 大小
* @param newCapacity
*/
public synchronized void setCapacity(int newCapacity) {
if (newCapacity < capacity) {
throw new IllegalStateException("队列长度设置异常");
}
this.capacity = newCapacity;
}
}
修改队列长度:
public class ScalableThreadChangeMain {
public static void main(String[] args) throws InterruptedException {
dynamicThreadPoolExecutor();
}
private static void dynamicThreadPoolExecutor() throws InterruptedException {
ThreadPoolExecutor executor = buildThreadPool();
for (int i = 0; i < 50; i++) {
executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
new Thread(() -> {
while (true) {
threadStatus(executor, "线程统计");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
TimeUnit.SECONDS.sleep(10);
threadStatus(executor, "改变之前");
//先设置maxPoolSize,不然会设置失败
executor.setMaximumPoolSize(10);
executor.setCorePoolSize(10);
ScalableLinkedBlockingQueue queue = (ScalableLinkedBlockingQueue) executor.getQueue();
queue.setCapacity(50);
threadStatus(executor, "改变之后");
Thread.currentThread().join();
}
private static void threadStatus(ThreadPoolExecutor executor, String name) {
ScalableLinkedBlockingQueue queue = (ScalableLinkedBlockingQueue) executor.getQueue();
String format = MessageFormat.format(
"{9}-{0}-{1}-: " +
"核心数线程:{2}, " +
"最大线程数: {3}, " +
"队列大小: {4}, " +
"活动线程数: {5}, " +
"任务完成数: {6}, " +
"当前排队线程数: {7}," +
"队列剩余大小: {8} " +
"队列使用率: {10}",
Thread.currentThread().getName(), name,
executor.getCorePoolSize(),
executor.getMaximumPoolSize(),
(queue.size() + queue.remainingCapacity()),
executor.getActiveCount(),
executor.getCompletedTaskCount(),
queue.size(),
queue.remainingCapacity(),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()),
countPercentage(queue.size(), (queue.size() + queue.remainingCapacity()))
);
System.out.println(format);
}
public static String countPercentage(int up, int down) {
return String.format("%1.2f%%",
Double.parseDouble(up + "") / Double.parseDouble(down + "") * 100);
}
private static ThreadPoolExecutor buildThreadPool() {
return new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS,
new ScalableLinkedBlockingQueue<>(45));
}
}
执行结果:
可以发现,任务队列长度也修改成50, 调整队列长度成功