Resolved issue: NETTY-68 (Make MemoryAwareThreadPoolExecutor.objectSizeEstimator property mutable)

This commit is contained in:
Trustin Lee 2008-11-20 08:10:49 +00:00
parent 678137b638
commit 70151828dc

View File

@ -88,10 +88,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
private static final InternalLogger logger = private static final InternalLogger logger =
InternalLoggerFactory.getInstance(MemoryAwareThreadPoolExecutor.class); InternalLoggerFactory.getInstance(MemoryAwareThreadPoolExecutor.class);
private volatile Settings settings = new Settings(0, 0); private volatile Settings settings;
// XXX Can be changed in runtime now. Make it mutable in 3.1.
private final ObjectSizeEstimator objectSizeEstimator;
private final ConcurrentMap<Channel, AtomicLong> channelCounters = private final ConcurrentMap<Channel, AtomicLong> channelCounters =
new ConcurrentHashMap<Channel, AtomicLong>(); new ConcurrentHashMap<Channel, AtomicLong>();
@ -175,7 +172,14 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
if (objectSizeEstimator == null) { if (objectSizeEstimator == null) {
throw new NullPointerException("objectSizeEstimator"); throw new NullPointerException("objectSizeEstimator");
} }
this.objectSizeEstimator = objectSizeEstimator; if (maxChannelMemorySize < 0) {
throw new IllegalArgumentException(
"maxChannelMemorySize: " + maxChannelMemorySize);
}
if (maxTotalMemorySize < 0) {
throw new IllegalArgumentException(
"maxTotalMemorySize: " + maxTotalMemorySize);
}
// Call allowCoreThreadTimeOut(true) using reflection // Call allowCoreThreadTimeOut(true) using reflection
// because it is not supported in Java 5. // because it is not supported in Java 5.
@ -189,15 +193,28 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
"supported in this platform."); "supported in this platform.");
} }
setMaxChannelMemorySize(maxChannelMemorySize); settings = new Settings(
setMaxTotalMemorySize(maxTotalMemorySize); objectSizeEstimator, maxChannelMemorySize, maxTotalMemorySize);
} }
/** /**
* Returns the {@link ObjectSizeEstimator} of this pool. * Returns the {@link ObjectSizeEstimator} of this pool.
*/ */
public ObjectSizeEstimator getObjectSizeEstimator() { public ObjectSizeEstimator getObjectSizeEstimator() {
return objectSizeEstimator; return settings.objectSizeEstimator;
}
/**
* Sets the {@link ObjectSizeEstimator} of this pool.
*/
public void setObjectSizeEstimator(ObjectSizeEstimator objectSizeEstimator) {
if (objectSizeEstimator == null) {
throw new NullPointerException("objectSizeEstimator");
}
settings = new Settings(
objectSizeEstimator,
settings.maxChannelMemorySize, settings.maxTotalMemorySize);
} }
/** /**
@ -222,7 +239,9 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
"can't be changed after a task is executed"); "can't be changed after a task is executed");
} }
settings = new Settings(maxChannelMemorySize, settings.maxTotalMemorySize); settings = new Settings(
settings.objectSizeEstimator,
maxChannelMemorySize, settings.maxTotalMemorySize);
} }
/** /**
@ -247,11 +266,17 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
"can't be changed after a task is executed"); "can't be changed after a task is executed");
} }
settings = new Settings(settings.maxChannelMemorySize, maxTotalMemorySize); settings = new Settings(
settings.objectSizeEstimator,
settings.maxChannelMemorySize, maxTotalMemorySize);
} }
@Override @Override
public void execute(Runnable command) { public void execute(Runnable command) {
if (!(command instanceof ChannelEventRunnable)) {
command = new MemoryAwareRunnable(command);
}
boolean pause = increaseCounter(command); boolean pause = increaseCounter(command);
doExecute(command); doExecute(command);
if (pause) { if (pause) {
@ -294,6 +319,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
protected void afterExecute(Runnable r, Throwable e) { protected void afterExecute(Runnable r, Throwable e) {
super.afterExecute(r, e); super.afterExecute(r, e);
} }
protected boolean increaseCounter(Runnable task) { protected boolean increaseCounter(Runnable task) {
if (!shouldCount(task)) { if (!shouldCount(task)) {
return false; return false;
@ -303,7 +329,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
long maxTotalMemorySize = settings.maxTotalMemorySize; long maxTotalMemorySize = settings.maxTotalMemorySize;
long maxChannelMemorySize = settings.maxChannelMemorySize; long maxChannelMemorySize = settings.maxChannelMemorySize;
int increment = getObjectSizeEstimator().estimateSize(task); int increment = settings.objectSizeEstimator.estimateSize(task);
long totalCounter = this.totalCounter.addAndGet(increment); long totalCounter = this.totalCounter.addAndGet(increment);
if (task instanceof ChannelEventRunnable) { if (task instanceof ChannelEventRunnable) {
@ -318,6 +344,8 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
channel.setReadable(false); channel.setReadable(false);
} }
} }
} else {
((MemoryAwareRunnable) task).estimatedSize = increment;
} }
//System.out.println("I: " + totalCounter + ", " + increment); //System.out.println("I: " + totalCounter + ", " + increment);
@ -337,7 +365,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
if (task instanceof ChannelEventRunnable) { if (task instanceof ChannelEventRunnable) {
increment = ((ChannelEventRunnable) task).estimatedSize; increment = ((ChannelEventRunnable) task).estimatedSize;
} else { } else {
increment = getObjectSizeEstimator().estimateSize(task); increment = ((MemoryAwareRunnable) task).estimatedSize;
} }
long totalCounter = this.totalCounter.addAndGet(-increment); long totalCounter = this.totalCounter.addAndGet(-increment);
@ -398,10 +426,13 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
} }
private static class Settings { private static class Settings {
final ObjectSizeEstimator objectSizeEstimator;
final long maxChannelMemorySize; final long maxChannelMemorySize;
final long maxTotalMemorySize; final long maxTotalMemorySize;
Settings(long maxChannelMemorySize, long maxTotalMemorySize) { Settings(ObjectSizeEstimator objectSizeEstimator,
long maxChannelMemorySize, long maxTotalMemorySize) {
this.objectSizeEstimator = objectSizeEstimator;
this.maxChannelMemorySize = maxChannelMemorySize; this.maxChannelMemorySize = maxChannelMemorySize;
this.maxTotalMemorySize = maxTotalMemorySize; this.maxTotalMemorySize = maxTotalMemorySize;
} }
@ -422,4 +453,17 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
} }
} }
} }
private static class MemoryAwareRunnable implements Runnable {
final Runnable task;
volatile int estimatedSize;
MemoryAwareRunnable(Runnable task) {
this.task = task;
}
public void run() {
task.run();
}
}
} }