先说结论:
静态内部类实现单例模式,是借助了类加载器加载类的特性实现的,类加载器在加载类时使用了synchronized关键字.
单例模式代码:
public class SingletonDemo {
public static void main(String[] args) {
SingletonDemo sd1 = getInstance();
SingletonDemo sd2 = getInstance();
System.out.println(sd1.equals(sd2));
}
private SingletonDemo(){};
private static class SingletonHolder{
private static SingletonDemo INSTANCE = new SingletonDemo();
}
public static SingletonDemo getInstance(){
return SingletonHolder.INSTANCE;
}
}
输出为:
true
首次执行getInstance()方法,调用SingletonHolder中的静态属性INSTANCE时,触发SingletonHolder类的加载,而new SingletonDemo()也会被执行,且只被执行一次.
在多线程环境下是如何实现同步的呢?这就要看ClassLoader类的源码了:
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
经过调试,可以确定的是,程序先进入了上面这个方法.但是点击F7进入的却不是下面这个方法:
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
PerfCounter.getParentDelegationTime().addTime(t1 - t0);
PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
进入的是ClassLoaders.AppClassLoader类中的loadClass()方法:
@Override
protected Class<?> loadClass(String cn, boolean resolve)
throws ClassNotFoundException
{
// for compatibility reasons, say where restricted package list has
// been updated to list API packages in the unnamed module.
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
int i = cn.lastIndexOf('.');
if (i != -1) {
sm.checkPackageAccess(cn.substring(0, i));
}
}
return super.loadClass(cn, resolve);
}
执行super.loadClass(),进入了BuiltinClassLoader类中的loadClass()方法:
@Override
protected Class<?> loadClass(String cn, boolean resolve)
throws ClassNotFoundException
{
Class<?> c = loadClassOrNull(cn, resolve);
if (c == null)
throw new ClassNotFoundException(cn);
return c;
}
执行loadClassOrNull()方法,然后进入同一个类中的loadClassOrNull()方法:
protected Class<?> loadClassOrNull(String cn, boolean resolve) {
synchronized (getClassLoadingLock(cn)) {
// check if already loaded
Class<?> c = findLoadedClass(cn);
if (c == null) {
// find the candidate module for this class
LoadedModule loadedModule = findLoadedModule(cn);
if (loadedModule != null) {
// package is in a module
BuiltinClassLoader loader = loadedModule.loader();
if (loader == this) {
if (VM.isModuleSystemInited()) {
c = findClassInModuleOrNull(loadedModule, cn);
}
} else {
// delegate to the other loader
c = loader.loadClassOrNull(cn);
}
} else {
// check parent
if (parent != null) {
c = parent.loadClassOrNull(cn);
}
// check class path
if (c == null && hasClassPath() && VM.isModuleSystemInited()) {
c = findClassOnClassPathOrNull(cn);
}
}
}
if (resolve && c != null)
resolveClass(c);
return c;
}
}
终于出现了,synchronized关键字!
调用链很长,但是都是在synchronized中了,就不继续往下走了.