在tomcat-embed-core-7.0.59包中,可以看到 Response源码中有一个关于MediaTypeCache的构造函数:
public class Response
implements HttpServletResponse {
// ----------------------------------------------------------- Constructors
private static final MediaTypeCache MEDIA_TYPE_CACHE =
new MediaTypeCache(100);
.......
}
而在MediaTypeCache类中,通过该构造函数,设置成员变量ConcurrentCache类中两个Map的初始化大小。
MediaTypeCache类:
public class MediaTypeCache {
private final ConcurrentCache<String,String[]> cache;
public MediaTypeCache(int size) {
cache = new ConcurrentCache<String,String[]>(size);
}
......
}
ConcurrentCache类
public final class ConcurrentCache<K,V> {
private final int size;
private final Map<K,V> eden;
private final Map<K,V> longterm;
public ConcurrentCache(int size) {
this.size = size;
this.eden = new ConcurrentHashMap<K,V>(size);
this.longterm = new WeakHashMap<K,V>(size);
}
public V get(K k) {
V v = this.eden.get(k);
if (v == null) {
synchronized (longterm) {
v = this.longterm.get(k);
}
if (v != null) {
this.eden.put(k, v);
}
}
return v;
}
public void put(K k, V v) {
if (this.eden.size() >= size) {
synchronized (longterm) {
this.longterm.putAll(this.eden);
}
this.eden.clear();
}
this.eden.put(k, v);
}
}
关键的问题就在于,ConcurrentCache类中利用eden和longterm来做分代缓存处理。在put操作中,我们能看到当eden中的实例数量超过初始化的size(100)的时候,会进行分代处理。
问题:根据HashMap的实际容量永远是2的幂数量和扩容机制,为什么tomcat不把size设置成2的幂? 为什么不把put操作中对size判断改成对eden容器的阈值进行判断?