面试的时候,常常会被问到这样一个问题:请您写出一个单例模式(Singleton Pattern)吧。好吧,写就写,这还不容易。顺手写一个:
- public
final class EagerSingleton - {
-
private static EagerSingleton singObj = new EagerSingleton(); -
-
private EagerSingleton(){ -
} -
-
public static EagerSingleton getSingleInstance(){ -
return singObj; -
} - }
这种写法就是所谓的饥饿模式,每个对象在没有使用之前就已经初始化了。这就可能带来潜在的性能问题:如果这个对象很大呢?没有使用这个对象之前,就把它加载到了内存中去是一种巨大的浪费。针对这种情况,我们可以对以上的代码进行改进,使用一种新的设计思想——延迟加载(Lazy-load Singleton)。
- public
final class LazySingleton - {
-
private static LazySingleton singObj = null; -
-
private LazySingleton(){ -
} -
-
public static LazySingleton getSingleInstance(){ -
if(null == singObj ) singObj = new LazySingleton(); -
return singObj; -
} - }
- public
final class ThreadSafeSingleton - {
-
private static ThreadSafeSingleton singObj = null; -
-
private ThreadSafeSingleton(){ -
} -
-
public static Synchronized ThreadSafeSingleton getSingleInstance(){ -
if(null == singObj ) singObj = new ThreadSafeSingleton(); -
return singObj; -
} - }
- public
final class DoubleCheckedSingleton - {
-
private static DoubleCheckedSingletonsi ngObj = null; -
-
private DoubleCheckedSingleton(){ -
} -
-
public static DoubleCheckedSingleton getSingleInstance(){ -
if(null == singObj ) { -
Synchronized(DoubleCheckedSingleton.class){ -
if(null == singObj) -
singObj = new DoubleCheckedSingleton(); -
} -
} -
return singObj; -
} - }
这种写法使得只有在加载新的对象进行同步,在加载完了之后,其他线程在第九行就可以判断跳过锁的的代价直接到第15行代码了。做到很好的并发度。
- public
class Singleton - {
-
private static class SingletonHolder -
{ -
public final static Singleton instance = new Singleton(); -
} -
-
public static Singleton getInstance() -
{ -
return SingletonHolder.instance; -
} - }