Skip to content

Commit 85b906c

Browse files
committed
Unify the handling of thread pools and their lifecycle. Fixes JCS-248
1 parent 3696088 commit 85b906c

7 files changed

Lines changed: 312 additions & 91 deletions

File tree

commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/CacheEventQueue.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,20 @@ public CacheEventQueue( final ICacheListener<K, V> listener, final long listener
5656
public CacheEventQueue( final ICacheListener<K, V> listener, final long listenerId, final String cacheName, final int maxFailure,
5757
final int waitBeforeRetry )
5858
{
59-
super( listener, listenerId, cacheName, maxFailure, waitBeforeRetry, null );
59+
super( listener, listenerId, cacheName, maxFailure, waitBeforeRetry, "CacheEventQueue.QProcessor-" + cacheName);
6060
}
6161

6262
/**
6363
* Create the thread pool.
6464
*
65-
* @param threadPoolName
6665
* @since 3.1
6766
*/
6867
@Override
69-
protected ExecutorService createPool(final String threadPoolName)
68+
protected ExecutorService createPool()
7069
{
7170
// create a default pool with one worker thread to mimic the SINGLE queue behavior
72-
return ThreadPoolManager.getInstance().createPool(
73-
new PoolConfiguration(false, 0, 1, 1, getWaitToDie(), WhenBlockedPolicy.RUN, 1),
74-
"CacheEventQueue.QProcessor-" + getCacheName());
71+
return ThreadPoolManager.getInstance().getExecutorService(poolName,
72+
new PoolConfiguration(false, 0, 1, 1, getWaitToDie(), WhenBlockedPolicy.RUN, 1));
7573
}
7674

7775
/**

commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/PooledCacheEventQueue.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.util.concurrent.BlockingQueue;
2525
import java.util.concurrent.ExecutorService;
2626
import java.util.concurrent.ThreadPoolExecutor;
27-
import java.util.concurrent.TimeUnit;
2827

2928
import org.apache.commons.jcs4.engine.behavior.ICacheListener;
3029
import org.apache.commons.jcs4.engine.stats.Stats;
@@ -51,6 +50,9 @@ public class PooledCacheEventQueue<K, V>
5150
/** The Thread Pool to execute events with. */
5251
protected ExecutorService pool;
5352

53+
/** The Thread Pool name in ThreadPoolManager. */
54+
protected String poolName;
55+
5456
/** The Thread Pool queue */
5557
protected BlockingQueue<Runnable> queue;
5658

@@ -73,14 +75,12 @@ public PooledCacheEventQueue( final ICacheListener<K, V> listener, final long li
7375
/**
7476
* Create the thread pool.
7577
*
76-
* @param threadPoolName
7778
* @since 3.1
7879
*/
79-
protected ExecutorService createPool(final String threadPoolName)
80+
protected ExecutorService createPool()
8081
{
8182
// this will share the same pool with other event queues by default.
82-
return ThreadPoolManager.getInstance().getExecutorService(
83-
threadPoolName == null ? "cache_event_queue" : threadPoolName );
83+
return ThreadPoolManager.getInstance().getExecutorService(poolName);
8484
}
8585

8686
/**
@@ -94,23 +94,7 @@ public synchronized void destroy(final Duration wait)
9494
if ( isWorking() )
9595
{
9696
setWorking(false);
97-
pool.shutdown();
98-
99-
if (wait.toSeconds() > 0)
100-
{
101-
try
102-
{
103-
if (!pool.awaitTermination(wait.toSeconds(), TimeUnit.SECONDS))
104-
{
105-
log.info( "No longer waiting for event queue to finish: {0}",
106-
this::getStatistics);
107-
}
108-
}
109-
catch (final InterruptedException e)
110-
{
111-
// ignore
112-
}
113-
}
97+
ThreadPoolManager.getInstance().disposeExecutorService(poolName, wait);
11498
log.info( "Cache event queue destroyed: {0}", this );
11599
}
116100
}
@@ -160,7 +144,8 @@ protected void initialize( final ICacheListener<K, V> listener, final long liste
160144
{
161145
super.initialize(listener, listenerId, cacheName, maxFailure, waitBeforeRetry);
162146

163-
pool = createPool(threadPoolName);
147+
poolName = threadPoolName == null ? "cache_event_queue" : threadPoolName;
148+
pool = createPool();
164149

165150
if (pool instanceof ThreadPoolExecutor tpe)
166151
{

commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/control/event/ElementEventQueue.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
public class ElementEventQueue
3939
implements IElementEventQueue
4040
{
41-
private static final String THREAD_PREFIX = "JCS-ElementEventQueue-";
41+
protected static final String POOL_NAME = "ElementEventQueue";
4242

4343
/** The logger */
4444
private static final Log log = Log.getLog( ElementEventQueue.class );
@@ -54,8 +54,8 @@ public class ElementEventQueue
5454
*/
5555
public ElementEventQueue()
5656
{
57-
queueProcessor = ThreadPoolManager.getInstance().createPool(
58-
new PoolConfiguration(false, 0, 1, 1, Duration.ZERO, WhenBlockedPolicy.RUN, 1), THREAD_PREFIX);
57+
queueProcessor = ThreadPoolManager.getInstance().getExecutorService(POOL_NAME,
58+
new PoolConfiguration(false, 0, 1, 1, Duration.ZERO, WhenBlockedPolicy.RUN, 1));
5959

6060
log.debug( "Constructed: {0}", this );
6161
}
@@ -91,8 +91,7 @@ public void dispose()
9191
{
9292
if (destroyed.compareAndSet(false, true))
9393
{
94-
// Pool will be shut down by the ThreadPoolManager
95-
// queueProcessor.shutdownNow();
94+
ThreadPoolManager.getInstance().disposeExecutorService(POOL_NAME);
9695
log.info( "Element event queue destroyed: {0}", this );
9796
}
9897
}

commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/discovery/UDPDiscoveryReceiver.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,9 @@ public UDPDiscoveryReceiver( final Consumer<UDPDiscoveryMessage> service,
105105
setService(service);
106106

107107
// create a small thread pool to handle a barrage
108-
this.pooledExecutor = ThreadPoolManager.getInstance().createPool(
108+
this.pooledExecutor = ThreadPoolManager.getInstance().getExecutorService("UDPDiscoveryReceiver",
109109
new PoolConfiguration(false, 0, maxPoolSize, maxPoolSize, Duration.ZERO,
110-
WhenBlockedPolicy.DISCARDOLDEST, maxPoolSize),
111-
"JCS-UDPDiscoveryReceiver-", Thread.MIN_PRIORITY);
110+
WhenBlockedPolicy.DISCARDOLDEST, maxPoolSize, Thread.MIN_PRIORITY));
112111

113112
log.info( "Constructing listener, [{0}:{1}]", multicastAddress, multicastPort );
114113
createSocket( multicastInterfaceString, multicastAddress, multicastPort );

commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/threadpool/PoolConfiguration.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ public record PoolConfiguration(
4747
WhenBlockedPolicy whenBlockedPolicy,
4848

4949
/** The number of threads to create on startup */
50-
int startUpSize
50+
int startUpSize,
51+
52+
/** The thread priority */
53+
int threadPriority
5154
) implements Cloneable
5255
{
5356
public enum WhenBlockedPolicy
@@ -88,12 +91,15 @@ public enum WhenBlockedPolicy
8891
/** Default startup size */
8992
private static final int DEFAULT_STARTUP_SIZE = DEFAULT_MINIMUM_POOL_SIZE;
9093

94+
/** Default thread priority */
95+
private static final int DEFAULT_THREAD_PRIORITY = Thread.NORM_PRIORITY;
96+
9197
/**
9298
* Default
9399
*/
94100
private static PoolConfiguration DEFAULT = new PoolConfiguration(DEFAULT_USE_BOUNDARY,
95101
DEFAULT_BOUNDARY_SIZE, DEFAULT_MAXIMUM_POOL_SIZE, DEFAULT_MINIMUM_POOL_SIZE,
96-
DEFAULT_KEEPALIVE_TIME, DEFAULT_WHEN_BLOCKED_POLICY, DEFAULT_STARTUP_SIZE);
102+
DEFAULT_KEEPALIVE_TIME, DEFAULT_WHEN_BLOCKED_POLICY, DEFAULT_STARTUP_SIZE, DEFAULT_THREAD_PRIORITY);
97103

98104
/**
99105
* @return An object containing the default settings
@@ -103,6 +109,22 @@ public static PoolConfiguration defaults()
103109
return DEFAULT;
104110
}
105111

112+
/**
113+
* Convenience constructor
114+
*
115+
* @param useBoundary Should we bound the queue
116+
* @param boundarySize If the queue is bounded, how big can it get
117+
* @param maximumPoolSize Only has meaning if a boundary is used
118+
* @param minimumPoolSize the exact number that will be used in a boundless queue
119+
* @param keepAliveTime How long idle threads above the minimum should be kept alive
120+
* @param whenBlockedPolicy Should be ABORT, BLOCK, RUN, WAIT, DISCARDOLDEST
121+
* @param startUpSize The number of threads to create on startup
122+
*/
123+
public PoolConfiguration(boolean useBoundary, int boundarySize, int maximumPoolSize, int minimumPoolSize, Duration keepAliveTime,
124+
WhenBlockedPolicy whenBlockedPolicy, int startUpSize)
125+
{
126+
this(useBoundary, boundarySize, maximumPoolSize, minimumPoolSize, keepAliveTime, whenBlockedPolicy, startUpSize, DEFAULT_THREAD_PRIORITY);
127+
}
106128

107129
/**
108130
* To string for debugging purposes.
@@ -118,7 +140,8 @@ public String toString()
118140
buf.append("minimumPoolSize = [").append(minimumPoolSize()).append("] ");
119141
buf.append("keepAliveTime = [").append(keepAliveTime()).append("] ");
120142
buf.append("whenBlockedPolicy = [").append(whenBlockedPolicy()).append("] ");
121-
buf.append("startUpSize = [").append(startUpSize()).append("]" );
143+
buf.append("startUpSize = [").append(startUpSize()).append("] " );
144+
buf.append("threadPriority = [").append(threadPriority()).append("]" );
122145
return buf.toString();
123146
}
124147
}

0 commit comments

Comments
 (0)