diff --git a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java index 20390650..f852e231 100644 --- a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java @@ -576,6 +576,23 @@ public abstract class AbstractDiscordSRV { + System.out.println(1); + try { + Thread.sleep(500000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + scheduler().run(() -> { + System.out.println(2); + try { + Thread.sleep(500000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + Status status = this.status.get(); if (status == Status.INITIALIZED || status.isShutdown()) { // Hasn't started or already shutting down/shutdown diff --git a/common/src/main/java/com/discordsrv/common/linking/requirelinking/RequiredLinkingModule.java b/common/src/main/java/com/discordsrv/common/linking/requirelinking/RequiredLinkingModule.java index eb2778ee..d07217ad 100644 --- a/common/src/main/java/com/discordsrv/common/linking/requirelinking/RequiredLinkingModule.java +++ b/common/src/main/java/com/discordsrv/common/linking/requirelinking/RequiredLinkingModule.java @@ -25,6 +25,7 @@ import com.discordsrv.common.linking.requirelinking.requirement.*; import com.discordsrv.common.linking.requirelinking.requirement.parser.RequirementParser; import com.discordsrv.common.module.type.AbstractModule; import com.discordsrv.common.scheduler.Scheduler; +import com.discordsrv.common.scheduler.executor.DynamicCachingThreadPoolExecutor; import com.discordsrv.common.scheduler.threadfactory.CountingThreadFactory; import java.util.ArrayList; @@ -54,7 +55,7 @@ public abstract class RequiredLinkingModule extends Abstra @Override public void enable() { - executor = new ThreadPoolExecutor( + executor = new DynamicCachingThreadPoolExecutor( 1, Math.max(2, Runtime.getRuntime().availableProcessors() / 2), 10, diff --git a/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java b/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java index ae07a1d8..4c5fa3a4 100644 --- a/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java +++ b/common/src/main/java/com/discordsrv/common/scheduler/StandardScheduler.java @@ -22,6 +22,7 @@ import com.discordsrv.api.event.bus.EventPriority; import com.discordsrv.api.event.bus.Subscribe; import com.discordsrv.api.event.events.lifecycle.DiscordSRVShuttingDownEvent; import com.discordsrv.common.DiscordSRV; +import com.discordsrv.common.scheduler.executor.DynamicCachingThreadPoolExecutor; import com.discordsrv.common.scheduler.threadfactory.CountingForkJoinWorkerThreadFactory; import com.discordsrv.common.scheduler.threadfactory.CountingThreadFactory; import org.jetbrains.annotations.NotNull; @@ -39,7 +40,7 @@ public class StandardScheduler implements Scheduler { public StandardScheduler(DiscordSRV discordSRV) { this( discordSRV, - new ThreadPoolExecutor( + new DynamicCachingThreadPoolExecutor( /* Core pool size */ 1, /* Max pool size: cpu cores - 2 or at least 4 */ diff --git a/common/src/main/java/com/discordsrv/common/scheduler/executor/DynamicCachingThreadPoolExecutor.java b/common/src/main/java/com/discordsrv/common/scheduler/executor/DynamicCachingThreadPoolExecutor.java new file mode 100644 index 00000000..bf058a95 --- /dev/null +++ b/common/src/main/java/com/discordsrv/common/scheduler/executor/DynamicCachingThreadPoolExecutor.java @@ -0,0 +1,43 @@ +package com.discordsrv.common.scheduler.executor; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.*; + +/** + * A {@link ThreadPoolExecutor} that acts like a {@link Executors#newCachedThreadPool()} with a max pool size while allowing queueing tasks. + */ +public class DynamicCachingThreadPoolExecutor extends ThreadPoolExecutor { + + private int corePoolSize; + + public DynamicCachingThreadPoolExecutor( + int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + @NotNull TimeUnit unit, + @NotNull BlockingQueue workQueue, + @NotNull ThreadFactory threadFactory + ) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); + this.corePoolSize = corePoolSize; + } + + @Override + public int getCorePoolSize() { + return corePoolSize; + } + + @Override + public void setCorePoolSize(int corePoolSize) { + this.corePoolSize = corePoolSize; + super.setCorePoolSize(this.corePoolSize); + } + + @Override + public synchronized void execute(@NotNull Runnable command) { + super.setCorePoolSize(getMaximumPoolSize()); + super.execute(command); + super.setCorePoolSize(this.corePoolSize); + } +}