summaryrefslogtreecommitdiffstats
path: root/src/main/java/org
diff options
context:
space:
mode:
authorSimon Rettberg2016-06-13 15:20:16 +0200
committerSimon Rettberg2016-06-13 15:20:16 +0200
commit83273ac89e48b41881d15168d47be658cf6aeebc (patch)
tree2b985fef430593ac9d27a54ceebbcd3f8f5306ff /src/main/java/org
parentCleanup, features, everything, nonsense commitmsg (diff)
downloaddnbd3-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.java85
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