diff options
author | Simon Rettberg | 2016-06-13 15:20:16 +0200 |
---|---|---|
committer | Simon Rettberg | 2016-06-13 15:20:16 +0200 |
commit | 83273ac89e48b41881d15168d47be658cf6aeebc (patch) | |
tree | 2b985fef430593ac9d27a54ceebbcd3f8f5306ff /src/main/java/org | |
parent | Cleanup, features, everything, nonsense commitmsg (diff) | |
download | dnbd3-status-83273ac89e48b41881d15168d47be658cf6aeebc.tar.gz dnbd3-status-83273ac89e48b41881d15168d47be658cf6aeebc.tar.xz dnbd3-status-83273ac89e48b41881d15168d47be658cf6aeebc.zip |
Fix CPU spinning in NanoHTTPd
Diffstat (limited to 'src/main/java/org')
-rw-r--r-- | src/main/java/org/openslx/util/GrowingThreadPoolExecutor.java | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/util/GrowingThreadPoolExecutor.java b/src/main/java/org/openslx/util/GrowingThreadPoolExecutor.java new file mode 100644 index 0000000..7b0b2d9 --- /dev/null +++ b/src/main/java/org/openslx/util/GrowingThreadPoolExecutor.java @@ -0,0 +1,85 @@ +package org.openslx.util; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Grows to maximum pool size before queueing. See + * http://stackoverflow.com/a/20153234/2043481 + */ +public class GrowingThreadPoolExecutor extends ThreadPoolExecutor { + private int userSpecifiedCorePoolSize; + private int taskCount; + + /** + * The default rejected execution handler + */ + private static final RejectedExecutionHandler defaultHandler = + new AbortPolicy(); + + public GrowingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, + TimeUnit unit, BlockingQueue<Runnable> workQueue) { + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, defaultHandler); + } + + public GrowingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, + BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); + } + + public GrowingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, + BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), + handler); + } + + public GrowingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, + BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); + userSpecifiedCorePoolSize = corePoolSize; + } + + @Override + public void execute(Runnable runnable) { + synchronized (this) { + taskCount++; + setCorePoolSizeToTaskCountWithinBounds(); + } + super.execute(runnable); + } + + @Override + protected void afterExecute(Runnable runnable, Throwable throwable) { + super.afterExecute(runnable, throwable); + synchronized (this) { + taskCount--; + setCorePoolSizeToTaskCountWithinBounds(); + } + } + + private void setCorePoolSizeToTaskCountWithinBounds() { + int threads = taskCount; + if (threads < userSpecifiedCorePoolSize) + threads = userSpecifiedCorePoolSize; + if (threads > getMaximumPoolSize()) + threads = getMaximumPoolSize(); + super.setCorePoolSize(threads); + } + + public void setCorePoolSize(int corePoolSize) { + synchronized (this) { + userSpecifiedCorePoolSize = corePoolSize; + } + } + + @Override + public int getCorePoolSize() { + synchronized (this) { + return userSpecifiedCorePoolSize; + } + } +}
\ No newline at end of file |