Added misuse detection to MemoryAwareThreadPoolExecutor and HashedWheelTimer, where a user can create too many instances

This commit is contained in:
Trustin Lee 2009-02-13 12:41:46 +00:00
parent 065218fd10
commit 3d355eb48a
2 changed files with 40 additions and 0 deletions

View File

@ -32,6 +32,8 @@ import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.jboss.netty.channel.Channel;
@ -87,6 +89,10 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
private static final InternalLogger logger =
InternalLoggerFactory.getInstance(MemoryAwareThreadPoolExecutor.class);
private static final int MISUSE_WARNING_THRESHOLD = 1024;
private static final AtomicInteger activeInstances = new AtomicInteger();
private static final AtomicBoolean loggedMisuseWarning = new AtomicBoolean();
private volatile Settings settings;
private final ConcurrentMap<Channel, AtomicLong> channelCounters =
@ -194,6 +200,23 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
settings = new Settings(
objectSizeEstimator, maxChannelMemorySize, maxTotalMemorySize);
// Misuse check
int activeInstances = MemoryAwareThreadPoolExecutor.activeInstances.incrementAndGet();
if (activeInstances >= MISUSE_WARNING_THRESHOLD &&
loggedMisuseWarning.compareAndSet(false, true)) {
logger.warn(
"There are too many active " + getClass().getSimpleName() +
" instances (" + activeInstances + ") - you should share " +
"the small number of instances to avoid excessive resource " +
"consumption.");
}
}
@Override
protected void terminated() {
super.terminated();
activeInstances.decrementAndGet();
}
/**

View File

@ -53,6 +53,10 @@ public class HashedWheelTimer implements Timer {
InternalLoggerFactory.getInstance(HashedWheelTimer.class);
private static final AtomicInteger id = new AtomicInteger();
private static final int MISUSE_WARNING_THRESHOLD = 1024;
private static final AtomicInteger activeInstances = new AtomicInteger();
private static final AtomicBoolean loggedMisuseWarning = new AtomicBoolean();
private final Worker worker = new Worker();
final Thread workerThread;
final AtomicBoolean shutdown = new AtomicBoolean();
@ -125,6 +129,17 @@ public class HashedWheelTimer implements Timer {
workerThread = threadFactory.newThread(new ThreadRenamingRunnable(
worker, "Hashed wheel timer #" + id.incrementAndGet()));
// Misuse check
int activeInstances = HashedWheelTimer.activeInstances.incrementAndGet();
if (activeInstances >= MISUSE_WARNING_THRESHOLD &&
loggedMisuseWarning.compareAndSet(false, true)) {
logger.warn(
"There are too many active " + getClass().getSimpleName() +
" instances (" + activeInstances + ") - you should share " +
"the small number of instances to avoid excessive resource " +
"consumption.");
}
}
@SuppressWarnings("unchecked")
@ -188,6 +203,8 @@ public class HashedWheelTimer implements Timer {
}
}
activeInstances.decrementAndGet();
Set<Timeout> unprocessedTimeouts = new HashSet<Timeout>();
for (Set<HashedWheelTimeout> bucket: wheel) {
unprocessedTimeouts.addAll(bucket);