mirror of
https://github.com/EsotericSoftware/reflectasm.git
synced 2025-01-28 21:00:24 +08:00
Try to load accessClass without synchronization
In EsotericSoftware/kryo#422 it's reported that the sychronization in `ConstructorAccess.get` on the loader is causing significant thread contention. This change tries to prevent this, via double checked locking. Because it's the same pattern it's also done for `FieldAccess` and `MethodAccess` as well.
This commit is contained in:
parent
88ec7037ea
commit
c5563b1205
@ -51,10 +51,13 @@ public abstract class ConstructorAccess<T> {
|
|||||||
Class accessClass;
|
Class accessClass;
|
||||||
|
|
||||||
AccessClassLoader loader = AccessClassLoader.get(type);
|
AccessClassLoader loader = AccessClassLoader.get(type);
|
||||||
synchronized (loader) {
|
|
||||||
try {
|
try {
|
||||||
accessClass = loader.loadClass(accessClassName);
|
accessClass = loader.loadClass(accessClassName);
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
synchronized (loader) {
|
||||||
|
try {
|
||||||
|
accessClass = loader.loadClass(accessClassName);
|
||||||
|
} catch (ClassNotFoundException ignored2) {
|
||||||
String accessClassNameInternal = accessClassName.replace('.', '/');
|
String accessClassNameInternal = accessClassName.replace('.', '/');
|
||||||
String classNameInternal = className.replace('.', '/');
|
String classNameInternal = className.replace('.', '/');
|
||||||
String enclosingClassNameInternal;
|
String enclosingClassNameInternal;
|
||||||
@ -100,6 +103,7 @@ public abstract class ConstructorAccess<T> {
|
|||||||
accessClass = loader.defineClass(accessClassName, cw.toByteArray());
|
accessClass = loader.defineClass(accessClassName, cw.toByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ConstructorAccess<T> access;
|
ConstructorAccess<T> access;
|
||||||
try {
|
try {
|
||||||
access = (ConstructorAccess<T>)accessClass.newInstance();
|
access = (ConstructorAccess<T>)accessClass.newInstance();
|
||||||
|
@ -121,10 +121,13 @@ public abstract class FieldAccess {
|
|||||||
Class accessClass = null;
|
Class accessClass = null;
|
||||||
|
|
||||||
AccessClassLoader loader = AccessClassLoader.get(type);
|
AccessClassLoader loader = AccessClassLoader.get(type);
|
||||||
synchronized (loader) {
|
|
||||||
try {
|
try {
|
||||||
accessClass = loader.loadClass(accessClassName);
|
accessClass = loader.loadClass(accessClassName);
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
synchronized (loader) {
|
||||||
|
try {
|
||||||
|
accessClass = loader.loadClass(accessClassName);
|
||||||
|
} catch (ClassNotFoundException ignored2) {
|
||||||
String accessClassNameInternal = accessClassName.replace('.', '/');
|
String accessClassNameInternal = accessClassName.replace('.', '/');
|
||||||
String classNameInternal = className.replace('.', '/');
|
String classNameInternal = className.replace('.', '/');
|
||||||
|
|
||||||
@ -155,6 +158,7 @@ public abstract class FieldAccess {
|
|||||||
accessClass = loader.defineClass(accessClassName, cw.toByteArray());
|
accessClass = loader.defineClass(accessClassName, cw.toByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
FieldAccess access = (FieldAccess)accessClass.newInstance();
|
FieldAccess access = (FieldAccess)accessClass.newInstance();
|
||||||
access.fieldNames = fieldNames;
|
access.fieldNames = fieldNames;
|
||||||
|
@ -107,10 +107,13 @@ public abstract class MethodAccess {
|
|||||||
Class accessClass;
|
Class accessClass;
|
||||||
|
|
||||||
AccessClassLoader loader = AccessClassLoader.get(type);
|
AccessClassLoader loader = AccessClassLoader.get(type);
|
||||||
synchronized (loader) {
|
|
||||||
try {
|
try {
|
||||||
accessClass = loader.loadClass(accessClassName);
|
accessClass = loader.loadClass(accessClassName);
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
synchronized (loader) {
|
||||||
|
try {
|
||||||
|
accessClass = loader.loadClass(accessClassName);
|
||||||
|
} catch (ClassNotFoundException ignored2) {
|
||||||
String accessClassNameInternal = accessClassName.replace('.', '/');
|
String accessClassNameInternal = accessClassName.replace('.', '/');
|
||||||
String classNameInternal = className.replace('.', '/');
|
String classNameInternal = className.replace('.', '/');
|
||||||
|
|
||||||
@ -272,6 +275,7 @@ public abstract class MethodAccess {
|
|||||||
accessClass = loader.defineClass(accessClassName, data);
|
accessClass = loader.defineClass(accessClassName, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
MethodAccess access = (MethodAccess)accessClass.newInstance();
|
MethodAccess access = (MethodAccess)accessClass.newInstance();
|
||||||
access.methodNames = methodNames;
|
access.methodNames = methodNames;
|
||||||
|
Loading…
Reference in New Issue
Block a user