|  |  |  | @@ -26,10 +26,9 @@ import java.util.logging.Logger; | 
		
	
		
			
				|  |  |  |  | import org.l2jmobius.Config; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /** | 
		
	
		
			
				|  |  |  |  |  * This class handles thread pooling system. It relies on two ThreadPoolExecutor arrays, which poolers number is generated using config. | 
		
	
		
			
				|  |  |  |  |  * <p> | 
		
	
		
			
				|  |  |  |  |  * Those arrays hold following pools: | 
		
	
		
			
				|  |  |  |  |  * </p> | 
		
	
		
			
				|  |  |  |  |  * 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> | 
		
	
	
		
			
				
					
					|  |  |  | @@ -39,59 +38,33 @@ public final class ThreadPool | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	private static final Logger LOGGER = Logger.getLogger(ThreadPool.class.getName()); | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	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; | 
		
	
		
			
				|  |  |  |  | 	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() | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		// 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); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 		// 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<Runnable>(100000)); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 		// 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(); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		// 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(() -> | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			purge(); | 
		
	
		
			
				|  |  |  |  | 		}, 600000, 600000); | 
		
	
		
			
				|  |  |  |  | 		}, 60000, 60000); | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 		LOGGER.info("ThreadPool: Initialized"); | 
		
	
		
			
				|  |  |  |  | 		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."); | 
		
	
		
			
				|  |  |  |  | 		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() | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			threadPool.purge(); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		for (ThreadPoolExecutor threadPool : INSTANT_POOLS) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			threadPool.purge(); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		SCHEDULED_POOL.purge(); | 
		
	
		
			
				|  |  |  |  | 		INSTANT_POOL.purge(); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	/** | 
		
	
	
		
			
				
					
					|  |  |  | @@ -102,16 +75,14 @@ public final class ThreadPool | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public static ScheduledFuture<?> schedule(Runnable runnable, long delay) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		synchronized (SCHEDULED_POOLS) | 
		
	
		
			
				|  |  |  |  | 		try | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			try | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			catch (Exception e) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				return null; | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			return SCHEDULED_POOL.schedule(new RunnableWrapper(runnable), delay, TimeUnit.MILLISECONDS); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		catch (Exception e) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace()); | 
		
	
		
			
				|  |  |  |  | 			return null; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
	
		
			
				
					
					|  |  |  | @@ -124,16 +95,14 @@ public final class ThreadPool | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public static ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialDelay, long period) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		synchronized (SCHEDULED_POOLS) | 
		
	
		
			
				|  |  |  |  | 		try | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			try | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				return SCHEDULED_POOLS[SCHEDULED_THREAD_RANDOMIZER++ % Config.SCHEDULED_THREAD_POOL_COUNT].scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			catch (Exception e) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				return null; | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			return SCHEDULED_POOL.scheduleAtFixedRate(new RunnableWrapper(runnable), initialDelay, period, TimeUnit.MILLISECONDS); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		catch (Exception e) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			LOGGER.warning(e.getMessage() + Config.EOL + e.getStackTrace()); | 
		
	
		
			
				|  |  |  |  | 			return null; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
	
		
			
				
					
					|  |  |  | @@ -143,50 +112,43 @@ public final class ThreadPool | 
		
	
		
			
				|  |  |  |  | 	 */ | 
		
	
		
			
				|  |  |  |  | 	public static void execute(Runnable runnable) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		synchronized (INSTANT_POOLS) | 
		
	
		
			
				|  |  |  |  | 		try | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			try | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				INSTANT_POOLS[INSTANT_THREAD_RANDOMIZER++ % Config.INSTANT_THREAD_POOL_COUNT].execute(new RunnableWrapper(runnable)); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			catch (Exception e) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			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[(SCHEDULED_POOLS.length + INSTANT_POOLS.length) * 10]; | 
		
	
		
			
				|  |  |  |  | 		final String[] stats = new String[20]; | 
		
	
		
			
				|  |  |  |  | 		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++] = " | -------"; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 		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; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
	
		
			
				
					
					|  |  |  | @@ -198,14 +160,8 @@ public final class ThreadPool | 
		
	
		
			
				|  |  |  |  | 		try | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			LOGGER.info("ThreadPool: Shutting down."); | 
		
	
		
			
				|  |  |  |  | 			for (ScheduledThreadPoolExecutor threadPool : SCHEDULED_POOLS) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				threadPool.shutdownNow(); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			for (ThreadPoolExecutor threadPool : INSTANT_POOLS) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				threadPool.shutdownNow(); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			SCHEDULED_POOL.shutdownNow(); | 
		
	
		
			
				|  |  |  |  | 			INSTANT_POOL.shutdownNow(); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		catch (Throwable t) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
	
		
			
				
					
					|  |  |  |   |