ThreadPool revert and path change.
This commit is contained in:
@@ -2,10 +2,14 @@
|
||||
# Threadpool Settings
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Specifies how many threads will be in the scheduled pool.
|
||||
# Default: 160
|
||||
ScheduledThreadPoolCount = 160
|
||||
# Determines the amount of scheduled thread pools. If set to -1, the server will decide the amount depending on the available processors.
|
||||
ScheduledThreadPoolCount = -1
|
||||
|
||||
# Specifies how many threads will be in the single instant pool.
|
||||
# Default: 120
|
||||
InstantThreadPoolCount = 120
|
||||
# Specifies how many threads will be in a single scheduled pool.
|
||||
ThreadsPerScheduledThreadPool = 4
|
||||
|
||||
# Determines the amount of instant thread pools. If set to -1, the server will decide the amount depending on the available processors.
|
||||
InstantThreadPoolCount = -1
|
||||
|
||||
# Specifies how many threads will be in a single instant pool.
|
||||
ThreadsPerInstantThreadPool = 2
|
@@ -71,7 +71,9 @@ public class Config
|
||||
public static List<Integer> KARMA_PROTECTED_ITEMS;
|
||||
// ThreadPool
|
||||
public static int SCHEDULED_THREAD_POOL_COUNT;
|
||||
public static int THREADS_PER_SCHEDULED_THREAD_POOL;
|
||||
public static int INSTANT_THREAD_POOL_COUNT;
|
||||
public static int THREADS_PER_INSTANT_THREAD_POOL;
|
||||
// Npc
|
||||
public static boolean SHOW_NPC_LEVEL;
|
||||
public static boolean SHOW_NPC_AGGRESSION;
|
||||
@@ -119,8 +121,18 @@ public class Config
|
||||
|
||||
// Load threadpool config file (if exists)
|
||||
final PropertiesParser threadpoolSettings = new PropertiesParser(THREADPOOL_CONFIG_FILE);
|
||||
SCHEDULED_THREAD_POOL_COUNT = threadpoolSettings.getInt("ScheduledThreadPoolCount", 40);
|
||||
INSTANT_THREAD_POOL_COUNT = threadpoolSettings.getInt("InstantThreadPoolCount", 20);
|
||||
SCHEDULED_THREAD_POOL_COUNT = threadpoolSettings.getInt("ScheduledThreadPoolCount", -1);
|
||||
if (SCHEDULED_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
SCHEDULED_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_SCHEDULED_THREAD_POOL = threadpoolSettings.getInt("ThreadsPerScheduledThreadPool", 4);
|
||||
INSTANT_THREAD_POOL_COUNT = threadpoolSettings.getInt("InstantThreadPoolCount", -1);
|
||||
if (INSTANT_THREAD_POOL_COUNT == -1)
|
||||
{
|
||||
INSTANT_THREAD_POOL_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
THREADS_PER_INSTANT_THREAD_POOL = threadpoolSettings.getInt("ThreadsPerInstantThreadPool", 2);
|
||||
|
||||
// Load NPC config file (if exists)
|
||||
final PropertiesParser npcSettings = new PropertiesParser(NPC_CONFIG_FILE);
|
||||
|
@@ -52,7 +52,7 @@ import org.l2jmobius.gameserver.handler.skillhandlers.HealSkill;
|
||||
import org.l2jmobius.gameserver.managers.GmListManager;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.network.ClientThread;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
import org.l2jmobius.loginserver.LoginController;
|
||||
|
||||
public class GameServer extends Thread
|
||||
|
@@ -31,7 +31,7 @@ import org.l2jmobius.gameserver.network.serverpackets.NpcInfo;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.PetInfo;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.PetItemList;
|
||||
import org.l2jmobius.gameserver.templates.Npc;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
|
||||
public class PetSummon implements IItemHandler
|
||||
{
|
||||
|
@@ -25,7 +25,7 @@ import org.l2jmobius.gameserver.model.actor.instance.ItemInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUser;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.SetupGauge;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
|
||||
public class ScrollOfEscape implements IItemHandler
|
||||
{
|
||||
|
@@ -20,7 +20,7 @@ package org.l2jmobius.gameserver.model;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
|
||||
public class Potion extends WorldObject
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ import org.l2jmobius.gameserver.IdManager;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
|
||||
import org.l2jmobius.gameserver.templates.Npc;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
import org.l2jmobius.util.Rnd;
|
||||
|
||||
public class Spawn
|
||||
|
@@ -36,7 +36,7 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.DropItem;
|
||||
import org.l2jmobius.gameserver.templates.Npc;
|
||||
import org.l2jmobius.gameserver.templates.Weapon;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
import org.l2jmobius.util.Rnd;
|
||||
|
||||
public class Attackable extends NpcInstance
|
||||
|
@@ -46,7 +46,7 @@ import org.l2jmobius.gameserver.network.serverpackets.StopMove;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.TeleportToLocation;
|
||||
import org.l2jmobius.gameserver.templates.Weapon;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
import org.l2jmobius.util.Chronos;
|
||||
import org.l2jmobius.util.Rnd;
|
||||
|
||||
|
@@ -37,7 +37,7 @@ import org.l2jmobius.gameserver.network.serverpackets.SetToLocation;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
|
||||
import org.l2jmobius.gameserver.templates.Npc;
|
||||
import org.l2jmobius.gameserver.templates.Weapon;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
|
||||
public class NpcInstance extends Creature
|
||||
{
|
||||
|
@@ -47,7 +47,7 @@ import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||
import org.l2jmobius.gameserver.templates.Npc;
|
||||
import org.l2jmobius.gameserver.templates.Weapon;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
|
||||
public class PetInstance extends Creature
|
||||
{
|
||||
|
@@ -80,7 +80,7 @@ import org.l2jmobius.gameserver.templates.Armor;
|
||||
import org.l2jmobius.gameserver.templates.CharTemplate;
|
||||
import org.l2jmobius.gameserver.templates.Item;
|
||||
import org.l2jmobius.gameserver.templates.Weapon;
|
||||
import org.l2jmobius.gameserver.threadpool.ThreadPool;
|
||||
import org.l2jmobius.gameserver.threads.ThreadPool;
|
||||
import org.l2jmobius.util.Chronos;
|
||||
import org.l2jmobius.util.Rnd;
|
||||
|
||||
|
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package org.l2jmobius.gameserver.threadpool;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
|
||||
/**
|
||||
* This class handles thread pooling system.<br>
|
||||
* It relies on two threadpool executors, which pool size is set using config.<br>
|
||||
* Those arrays hold following pools:<br>
|
||||
* <ul>
|
||||
* <li>Scheduled pool keeps a track about incoming, future events.</li>
|
||||
* <li>Instant pool handles short-life events.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static final ScheduledThreadPoolExecutor SCHEDULED_POOL = new ScheduledThreadPoolExecutor(Config.SCHEDULED_THREAD_POOL_COUNT);
|
||||
private static final ThreadPoolExecutor INSTANT_POOL = new ThreadPoolExecutor(Config.INSTANT_THREAD_POOL_COUNT, Config.INSTANT_THREAD_POOL_COUNT, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000));
|
||||
|
||||
public static void init()
|
||||
{
|
||||
// Set pool options.
|
||||
SCHEDULED_POOL.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
SCHEDULED_POOL.setRemoveOnCancelPolicy(true);
|
||||
SCHEDULED_POOL.prestartAllCoreThreads();
|
||||
INSTANT_POOL.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
INSTANT_POOL.prestartAllCoreThreads();
|
||||
|
||||
// Launch purge task.
|
||||
scheduleAtFixedRate(ThreadPool::purge, 60000, 60000);
|
||||
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
LOGGER.info("...scheduled pool executor with " + Config.SCHEDULED_THREAD_POOL_COUNT + " total threads.");
|
||||
LOGGER.info("...instant pool executor with " + Config.INSTANT_THREAD_POOL_COUNT + " total threads.");
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
SCHEDULED_POOL.purge();
|
||||
INSTANT_POOL.purge();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SCHEDULED_POOL.schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SCHEDULED_POOL.scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
INSTANT_POOL.execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[20];
|
||||
int pos = 0;
|
||||
|
||||
stats[pos++] = "Scheduled pool:";
|
||||
stats[pos++] = " |- ActiveCount: ...... " + SCHEDULED_POOL.getActiveCount();
|
||||
stats[pos++] = " |- CorePoolSize: ..... " + SCHEDULED_POOL.getCorePoolSize();
|
||||
stats[pos++] = " |- PoolSize: ......... " + SCHEDULED_POOL.getPoolSize();
|
||||
stats[pos++] = " |- LargestPoolSize: .. " + SCHEDULED_POOL.getLargestPoolSize();
|
||||
stats[pos++] = " |- MaximumPoolSize: .. " + SCHEDULED_POOL.getMaximumPoolSize();
|
||||
stats[pos++] = " |- CompletedTaskCount: " + SCHEDULED_POOL.getCompletedTaskCount();
|
||||
stats[pos++] = " |- QueuedTaskCount: .. " + SCHEDULED_POOL.getQueue().size();
|
||||
stats[pos++] = " |- TaskCount: ........ " + SCHEDULED_POOL.getTaskCount();
|
||||
stats[pos++] = " | -------";
|
||||
|
||||
stats[pos++] = "Instant pool:";
|
||||
stats[pos++] = " |- ActiveCount: ...... " + INSTANT_POOL.getActiveCount();
|
||||
stats[pos++] = " |- CorePoolSize: ..... " + INSTANT_POOL.getCorePoolSize();
|
||||
stats[pos++] = " |- PoolSize: ......... " + INSTANT_POOL.getPoolSize();
|
||||
stats[pos++] = " |- LargestPoolSize: .. " + INSTANT_POOL.getLargestPoolSize();
|
||||
stats[pos++] = " |- MaximumPoolSize: .. " + INSTANT_POOL.getMaximumPoolSize();
|
||||
stats[pos++] = " |- CompletedTaskCount: " + INSTANT_POOL.getCompletedTaskCount();
|
||||
stats[pos++] = " |- QueuedTaskCount: .. " + INSTANT_POOL.getQueue().size();
|
||||
stats[pos++] = " |- TaskCount: ........ " + INSTANT_POOL.getTaskCount();
|
||||
stats[pos++] = " | -------";
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown thread pooling system correctly. Send different informations.
|
||||
*/
|
||||
public static void shutdown()
|
||||
{
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
SCHEDULED_POOL.shutdownNow();
|
||||
INSTANT_POOL.shutdownNow();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOGGER.info("ThreadPool: Problem at Shutting down. " + t.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -15,13 +15,15 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package org.l2jmobius.gameserver.threadpool;
|
||||
package org.l2jmobius.gameserver.threads;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
|
||||
/**
|
||||
* @author NB4L1
|
||||
*/
|
||||
@@ -30,22 +32,22 @@ public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler
|
||||
private static final Logger LOGGER = Logger.getLogger(RejectedExecutionHandlerImpl.class.getName());
|
||||
|
||||
@Override
|
||||
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
|
||||
public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor)
|
||||
{
|
||||
if (executor.isShutdown())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.warning(r + " from " + executor + " " + new RejectedExecutionException());
|
||||
LOGGER.warning(runnable.getClass().getSimpleName() + Config.EOL + runnable + " from " + executor + " " + new RejectedExecutionException());
|
||||
|
||||
if (Thread.currentThread().getPriority() > Thread.NORM_PRIORITY)
|
||||
{
|
||||
new Thread(r).start();
|
||||
new Thread(runnable).start();
|
||||
}
|
||||
else
|
||||
{
|
||||
r.run();
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
@@ -15,13 +15,10 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package org.l2jmobius.gameserver.threadpool;
|
||||
package org.l2jmobius.gameserver.threads;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class RunnableWrapper implements Runnable
|
||||
{
|
||||
private final Runnable _runnable;
|
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package org.l2jmobius.gameserver.threads;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
|
||||
/**
|
||||
* This class handles thread pooling system.<br>
|
||||
* It relies on two ThreadPoolExecutor arrays, which pool size is set using config.<br>
|
||||
* Those arrays hold following pools:<br>
|
||||
* <ul>
|
||||
* <li>Scheduled pool keeps a track about incoming, future events.</li>
|
||||
* <li>Instant pool handles short-life events.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class ThreadPool
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName());
|
||||
|
||||
private static final ScheduledThreadPoolExecutor[] SCHEDULED_POOLS = new ScheduledThreadPoolExecutor[Config.SCHEDULED_THREAD_POOL_COUNT];
|
||||
private static final ThreadPoolExecutor[] INSTANT_POOLS = new ThreadPoolExecutor[Config.INSTANT_THREAD_POOL_COUNT];
|
||||
private static int SCHEDULED_THREAD_RANDOMIZER = 0;
|
||||
private static int INSTANT_THREAD_RANDOMIZER = 0;
|
||||
|
||||
public static void init()
|
||||
{
|
||||
LOGGER.info("ThreadPool: Initialized");
|
||||
|
||||
// Feed scheduled pool.
|
||||
for (int i = 0; i < Config.SCHEDULED_THREAD_POOL_COUNT; i++)
|
||||
{
|
||||
SCHEDULED_POOLS[i] = new ScheduledThreadPoolExecutor(Config.THREADS_PER_SCHEDULED_THREAD_POOL);
|
||||
}
|
||||
|
||||
LOGGER.info("..." + Config.SCHEDULED_THREAD_POOL_COUNT + " scheduled pool executors with " + (Config.SCHEDULED_THREAD_POOL_COUNT * Config.THREADS_PER_SCHEDULED_THREAD_POOL) + " total threads.");
|
||||
|
||||
// Feed instant pool.
|
||||
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<>(100000));
|
||||
}
|
||||
|
||||
LOGGER.info("..." + Config.INSTANT_THREAD_POOL_COUNT + " instant pool executors with " + (Config.INSTANT_THREAD_POOL_COUNT * Config.THREADS_PER_INSTANT_THREAD_POOL) + " total threads.");
|
||||
|
||||
// Prestart core threads.
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.setRemoveOnCancelPolicy(true);
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandlerImpl());
|
||||
threadPool.prestartAllCoreThreads();
|
||||
}
|
||||
|
||||
// Launch purge task.
|
||||
scheduleAtFixedRate(ThreadPool::purge, 60000, 60000);
|
||||
}
|
||||
|
||||
public static void purge()
|
||||
{
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.purge();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.purge();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 runnable, long delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given task sometime in the future.
|
||||
* @param runnable : the task to execute.
|
||||
*/
|
||||
public static void execute(Runnable runnable)
|
||||
{
|
||||
try
|
||||
{
|
||||
INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace());
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getStats()
|
||||
{
|
||||
final String[] stats = new String[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10];
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < SCHEDULED_POOLS.length; i++)
|
||||
{
|
||||
final ScheduledThreadPoolExecutor threadPool = SCHEDULED_POOLS[i];
|
||||
stats[pos++] = "Scheduled pool #" + i + ":";
|
||||
stats[pos++] = " |- ActiveCount: ...... " + threadPool.getActiveCount();
|
||||
stats[pos++] = " |- CorePoolSize: ..... " + threadPool.getCorePoolSize();
|
||||
stats[pos++] = " |- PoolSize: ......... " + threadPool.getPoolSize();
|
||||
stats[pos++] = " |- LargestPoolSize: .. " + threadPool.getLargestPoolSize();
|
||||
stats[pos++] = " |- MaximumPoolSize: .. " + threadPool.getMaximumPoolSize();
|
||||
stats[pos++] = " |- CompletedTaskCount: " + threadPool.getCompletedTaskCount();
|
||||
stats[pos++] = " |- QueuedTaskCount: .. " + threadPool.getQueue().size();
|
||||
stats[pos++] = " |- TaskCount: ........ " + threadPool.getTaskCount();
|
||||
stats[pos++] = " | -------";
|
||||
}
|
||||
|
||||
for (int i = 0; i < INSTANT_POOLS.length; i++)
|
||||
{
|
||||
final ThreadPoolExecutor threadPool = INSTANT_POOLS[i];
|
||||
stats[pos++] = "Instant pool #" + i + ":";
|
||||
stats[pos++] = " |- ActiveCount: ...... " + threadPool.getActiveCount();
|
||||
stats[pos++] = " |- CorePoolSize: ..... " + threadPool.getCorePoolSize();
|
||||
stats[pos++] = " |- PoolSize: ......... " + threadPool.getPoolSize();
|
||||
stats[pos++] = " |- LargestPoolSize: .. " + threadPool.getLargestPoolSize();
|
||||
stats[pos++] = " |- MaximumPoolSize: .. " + threadPool.getMaximumPoolSize();
|
||||
stats[pos++] = " |- CompletedTaskCount: " + threadPool.getCompletedTaskCount();
|
||||
stats[pos++] = " |- QueuedTaskCount: .. " + threadPool.getQueue().size();
|
||||
stats[pos++] = " |- TaskCount: ........ " + threadPool.getTaskCount();
|
||||
stats[pos++] = " | -------";
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown thread pooling system correctly. Send different informations.
|
||||
*/
|
||||
public static void shutdown()
|
||||
{
|
||||
try
|
||||
{
|
||||
LOGGER.info("ThreadPool: Shutting down.");
|
||||
|
||||
for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
for (ThreadPoolExecutor threadPool : INSTANT_POOLS)
|
||||
{
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOGGER.info("ThreadPool: Problem at Shutting down. " + t.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user