ThreadPool class improvements.
This commit is contained in:
parent
0c3a512bd3
commit
36457c0bec
@ -1272,8 +1272,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1279,8 +1279,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1287,8 +1287,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1280,8 +1280,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1275,8 +1275,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1275,8 +1275,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1282,8 +1282,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -2330,8 +2330,16 @@ public final class Config
|
||||
LOG_ITEMS = Boolean.valueOf(devSettings.getProperty("LogItems", "false"));
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = Integer.parseInt(devSettings.getProperty("ScheduledThreadPoolCount", "-1"));
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = Integer.parseInt(devSettings.getProperty("ThreadsPerScheduledThreadPool", "4"));
|
||||
INSTANT_THREAD_POOL_COUNT = Integer.parseInt(devSettings.getProperty("InstantThreadPoolCount", "-1"));
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = Integer.parseInt(devSettings.getProperty("ThreadsPerInstantThreadPool", "2"));
|
||||
|
||||
LAZY_CACHE = Boolean.valueOf(devSettings.getProperty("LazyCache", "false"));
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1441,8 +1441,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1219,8 +1219,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1223,8 +1223,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1223,8 +1223,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
@ -1223,8 +1223,16 @@ public final class Config
|
||||
SERVER_LIST_BRACKET = serverSettings.getBoolean("ServerListBrackets", false);
|
||||
|
||||
SCHEDULED_THREAD_POOL_COUNT = serverSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = serverSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = serverSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = serverSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
IO_PACKET_THREAD_CORE_SIZE = serverSettings.getInt("UrgentPacketThreadCoreSize", 2);
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class RunnableWrapper implements Runnable
|
||||
{
|
||||
_runnable.run();
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
final Thread t = Thread.currentThread();
|
||||
final UncaughtExceptionHandler h = t.getUncaughtExceptionHandler();
|
||||
|
@ -39,37 +39,21 @@ public final class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS;
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS;
|
||||
private static int THREAD_POOL_RANDOMIZER;
|
||||
private static ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static volatile int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static volatile int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
/**
|
||||
* Init the different pools, based on Config. It is launched only once, on Gameserver instance.
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
// Feed scheduled pool.
|
||||
int scheduledPoolCount = Config.SCHEDULED_THREAD_POOL_COUNT;
|
||||
if (scheduledPoolCount == -1)
|
||||
{
|
||||
scheduledPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[scheduledPoolCount];
|
||||
for (int i = 0; i < scheduledPoolCount; i++)
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
// Feed instant pool.
|
||||
int instantPoolCount = Config.INSTANT_THREAD_POOL_COUNT;
|
||||
if (instantPoolCount == -1)
|
||||
{
|
||||
instantPoolCount = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
INSTANT_POOLS = new ThreadPoolExecutor[instantPoolCount];
|
||||
for (int i = 0; i < instantPoolCount; i++)
|
||||
for (int i = 0; i < Config.INSTANT_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
INSTANT_POOLS[i] = new ThreadPoolExecutor(Config.THREADS_PER_INSTANT_THREAD_POOL, Config.THREADS_PER_INSTANT_THREAD_POOL, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
}
|
||||
@ -80,7 +64,6 @@ public final class ThreadPool
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
@ -94,33 +77,33 @@ public final class ThreadPool
|
||||
}, 600000, 600000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("..." + scheduledPoolCount + " scheduled pool executors with " + (scheduledPoolCount * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + instantPoolCount + " instant pool executors with " + (instantPoolCount * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool1 : SCHEDULED_POOLS)
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool1.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
for (ThreadPoolExecutor threadPool2 : INSTANT_POOLS)
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool2.purge();
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a one-shot action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* Creates and executes a one-shot action that becomes enabled after the given delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will return null upon completion.
|
||||
*/
|
||||
public static ScheduledFuture<?> schedule(Runnable r, long delay)
|
||||
public static ScheduledFuture<?> schedule(Runnable runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).schedule(new RunnableWrapper(r), delay, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -129,17 +112,17 @@ public final class ThreadPool
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a periodic action that becomes enabled after a delay. The pool is chosen based on pools activity.
|
||||
* @param r : the task to execute.
|
||||
* @param delay : the time from now to delay execution.
|
||||
* Creates and executes a periodic action that becomes enabled first after the given initial delay.
|
||||
* @param runnable : the task to execute.
|
||||
* @param initialDelay : the time to delay first execution.
|
||||
* @param period : the period between successive executions.
|
||||
* @return a ScheduledFuture representing pending completion of the task and whose get() method will throw an exception upon cancellation.
|
||||
* @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable r, long delay, long period)
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getPool(SCHEDULED_POOLS).scheduleAtFixedRate(new RunnableWrapper(r), delay, period, TimeUnit.MILLISECONDS);
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -149,29 +132,19 @@ public final class ThreadPool
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param r : the task to execute.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable r)
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
getPool(INSTANT_POOLS).execute(new RunnableWrapper(r));
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> : The pool type.
|
||||
* @param threadPools : The pool array to check.
|
||||
* @return the less fed pool.
|
||||
*/
|
||||
private static <T> T getPool(T[] threadPools)
|
||||
{
|
||||
return threadPools[THREAD_POOL_RANDOMIZER++ % threadPools.length];
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
@ -215,12 +188,10 @@ public final class ThreadPool
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
|
Loading…
Reference in New Issue
Block a user