Last active
February 11, 2025 21:29
-
-
Save simonis/c6af7dae5e21f640ce417c61833e6a50 to your computer and use it in GitHub Desktop.
Concurrent class initialization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Method; | |
import java.net.URL; | |
import java.net.URLClassLoader; | |
public class ClassInit { | |
static final int CLASSLOADERS = Integer.getInteger("classloaders", 3); | |
static final int THREADS = Integer.getInteger("threads", 3); | |
static class MyClassLoader extends URLClassLoader { | |
public MyClassLoader() { | |
super(new URL[] { ClassInit.class.getProtectionDomain().getCodeSource().getLocation() }); | |
} | |
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { | |
if (name.startsWith("ClassInit$Singleton") || name.startsWith("ClassInit$UseSingleton")) { | |
Class<?> c = findClass(name); | |
if (resolve) { | |
resolveClass(c); | |
} | |
return c; | |
} | |
else { | |
return super.loadClass(name, resolve); | |
} | |
} | |
} | |
static class Singleton { | |
public static Singleton singleton; | |
static { | |
new Singleton(); | |
} | |
private Singleton() { | |
singleton = this; | |
} | |
public int min(int i, int j) { | |
return Math.min(i, j); | |
} | |
} | |
static class UseSingleton { | |
static volatile boolean start = false; | |
public static void useSingleton() { | |
int THREADS = Integer.getInteger("threads", 3); | |
for (int i = 0; i < THREADS; i++) { | |
final int j = i; | |
new Thread() { | |
public void run() { | |
while (!start) Thread.onSpinWait(); | |
Singleton.singleton.min(j, THREADS); | |
} | |
} . start(); | |
} | |
start = true; | |
} | |
} | |
public static void main(String args[]) throws Exception { | |
for (int i = 0; i < THREADS; i++) { | |
new Thread() { | |
public void run() { | |
for (int i = 0; i < CLASSLOADERS; i++) { | |
try { | |
Method get = new MyClassLoader().loadClass("ClassInit$UseSingleton").getDeclaredMethod("useSingleton"); | |
get.setAccessible(true); | |
get.invoke(null); | |
} catch (Exception e) { | |
throw new Error(e); | |
} | |
} | |
} | |
} . start(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment