提交 ca0148c2 编写于 作者: C chegar

6806649: synchronization bottleneck when constructing Thread subclasses

Summary: Replace subclass audits synchronization with ConcurrentHashMap with weakly referenced Class keys
Reviewed-by: peterjones, dholmes, martin
上级 db939964
......@@ -25,13 +25,17 @@
package java.lang;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.LockSupport;
import sun.misc.SoftCache;
import sun.nio.ch.Interruptible;
import sun.security.util.SecurityConstants;
......@@ -1640,8 +1644,17 @@ class Thread implements Runnable {
new RuntimePermission("enableContextClassLoaderOverride");
/** cache of subclass security audit results */
private static final SoftCache subclassAudits = new SoftCache(10);
/* Replace with ConcurrentReferenceHashMap when/if it appears in a future
* release */
private static class Caches {
/** cache of subclass security audit results */
static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
new ConcurrentHashMap<WeakClassKey,Boolean>();
/** queue for WeakReferences to audited subclasses */
static final ReferenceQueue<Class<?>> subclassAuditsQueue =
new ReferenceQueue<Class<?>>();
}
/**
* Verifies that this (possibly subclass) instance can be constructed
......@@ -1652,19 +1665,15 @@ class Thread implements Runnable {
private static boolean isCCLOverridden(Class cl) {
if (cl == Thread.class)
return false;
Boolean result = null;
synchronized (subclassAudits) {
result = (Boolean) subclassAudits.get(cl);
if (result == null) {
/*
* Note: only new Boolean instances (i.e., not Boolean.TRUE or
* Boolean.FALSE) must be used as cache values, otherwise cache
* entry will pin associated class.
*/
result = new Boolean(auditSubclass(cl));
subclassAudits.put(cl, result);
}
processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result = Caches.subclassAudits.get(key);
if (result == null) {
result = Boolean.valueOf(auditSubclass(cl));
Caches.subclassAudits.putIfAbsent(key, result);
}
return result.booleanValue();
}
......@@ -1967,6 +1976,68 @@ class Thread implements Runnable {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
/**
* Removes from the specified map any keys that have been enqueued
* on the specified reference queue.
*/
static void processQueue(ReferenceQueue<Class<?>> queue,
ConcurrentMap<? extends
WeakReference<Class<?>>, ?> map)
{
Reference<? extends Class<?>> ref;
while((ref = queue.poll()) != null) {
map.remove(ref);
}
}
/**
* Weak key for Class objects.
**/
static class WeakClassKey extends WeakReference<Class<?>> {
/**
* saved value of the referent's identity hash code, to maintain
* a consistent hash code after the referent has been cleared
*/
private final int hash;
/**
* Create a new WeakClassKey to the given object, registered
* with a queue.
*/
WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
super(cl, refQueue);
hash = System.identityHashCode(cl);
}
/**
* Returns the identity hash code of the original referent.
*/
@Override
public int hashCode() {
return hash;
}
/**
* Returns true if the given object is this identical
* WeakClassKey instance, or, if this object's referent has not
* been cleared, if the given object is another WeakClassKey
* instance with the identical non-null referent as this one.
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof WeakClassKey) {
Object referent = get();
return (referent != null) &&
(referent == ((WeakClassKey) obj).get());
} else {
return false;
}
}
}
/* Some private helper methods */
private native void setPriority0(int newPriority);
private native void stop0(Object o);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册