2323
2424public final class LambdaFactory {
2525 private static final class LambdaClassLoader extends ClassLoader {
26+ private static final Lock GLOBAL_LOCK = new ReentrantLock ();
2627 private static final Map <ClassLoader , WeakReference <LambdaClassLoader >> KNOWN_LOADERS = new WeakHashMap <>();
2728
2829 static {
@@ -39,15 +40,21 @@ private LambdaClassLoader(final ClassLoader parent) {
3940 }
4041
4142 private static LambdaClassLoader findLoader (final MethodHandles .Lookup lookup ) {
42- final ClassLoader lookupClassLoader = lookup .lookupClass ().getClassLoader ();
43- final WeakReference <LambdaClassLoader > loaderRef = KNOWN_LOADERS .get (lookupClassLoader );
44- if (loaderRef == null || loaderRef .get () == null ) {
45- // LambdaClassLoader reference was lost (or it never existed), so recreate
46- final LambdaClassLoader loader = new LambdaClassLoader (lookupClassLoader );
47- KNOWN_LOADERS .put (loader , new WeakReference <>(loader ));
48- return loader ;
43+ GLOBAL_LOCK .lock ();
44+ try {
45+ final ClassLoader lookupClassLoader = lookup .lookupClass ().getClassLoader ();
46+ final WeakReference <LambdaClassLoader > loaderRef = KNOWN_LOADERS .get (lookupClassLoader );
47+ final LambdaClassLoader alreadyPresentLoader = loaderRef == null ? null : loaderRef .get ();
48+ if (alreadyPresentLoader == null ) {
49+ // LambdaClassLoader reference was lost (or it never existed), so recreate
50+ final LambdaClassLoader loader = new LambdaClassLoader (lookupClassLoader );
51+ KNOWN_LOADERS .put (loader , new WeakReference <>(loader ));
52+ return loader ;
53+ }
54+ return alreadyPresentLoader ;
55+ } finally {
56+ GLOBAL_LOCK .unlock ();
4957 }
50- return loaderRef .get ();
5158 }
5259
5360 LambdaClassLoader registerLambda (final String name , final byte [] data ) {
@@ -65,25 +72,16 @@ LambdaClassLoader registerLambda(final String name, final byte[] data) {
6572
6673 @ Override
6774 protected Class <?> findClass (final String name ) throws ClassNotFoundException {
68- // Step 1: try loading the class directly without locking; there should never be an instance where a thread
69- // is trying to load a class that is being registered on another thread
70- Class <?> lambdaClass = this .tryLoadLambdaClass (name );
71- if (lambdaClass != null ) {
72- return lambdaClass ;
73- }
74-
75- // Step 2: if the previous step failed, let's retry with locking just in case the above situation happened
7675 this .lock .lock ();
7776 try {
78- lambdaClass = this .tryLoadLambdaClass (name );
77+ final Class <?> lambdaClass = this .tryLoadLambdaClass (name );
7978 if (lambdaClass != null ) {
8079 return lambdaClass ;
8180 }
8281 } finally {
8382 this .lock .unlock ();
8483 }
8584
86- // Step 3: Defer to default behavior
8785 return super .findClass (name );
8886 }
8987
0 commit comments