懒汉模式为什么是线程安全的?这个大家基本都能看懂,加了锁了嘛!
饿汉模式为什么是安全的?因为静态对象是在类加载中就初始化了。
那为什么类加载过程是线程安全的呢?
之前没有考虑过,现在知道了,因为loadClass对象加了锁了
所以说饿汉模式是不加锁的,是不准确的
有答案说,使用ThreadLocal可以做到不加锁就做到线程安全的单例模式,但是这样的单例得出的只能保证线程内部的单例,多线程之间的数据不是单例的
当然,饿汉模式懒汉模式以及静态内部类模式就真的能做到单例?
也不是,使用反射或者序列化的方式,就可以做到多例
如何解决,构造器中加入首次判断(双重锁试用下,保证线程安全)以及加一个readResolve方法
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
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
ThreadLocal的优点:
线程内安全
每个线程的ThreadLocal都是自己独有的,不用考虑线程安全问题
不用经常创建新对象,ThreadLocal的数量和线程池内的线程数一致