public class Singleton {private final static Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() { return Singleton.INSTANCE; }
protected Object clone() {throw new CloneNotSupportedException();}}
如果您想要延迟加载并且希望您的单例是线程安全的,请尝试双重检查模式:
public class Singleton {private static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {if(null == instance) {synchronized(Singleton.class) {if(null == instance) {instance = new Singleton();}}}return instance;}
protected Object clone() {throw new CloneNotSupportedException();}}
class Foo {private static volatile Bar bar = null;public static Bar getBar() {if (bar == null) {synchronized(Foo.class) {if (bar == null)bar = new Bar();}}return bar;}}
public final class Foo {
private static final Foo INSTANCE = new Foo();
private Foo() {if (INSTANCE != null) {throw new IllegalStateException("Already instantiated");}}
public static Foo getInstance() {return INSTANCE;}
public Object clone() throws CloneNotSupportedException{throw new CloneNotSupportedException("Cannot clone instance of this class");}}
让我们回顾一下代码。首先,你希望类是最终的。在这种情况下,我使用了final关键字让用户知道它是最终的。然后你需要将构造函数设为私有,以防止用户创建自己的Foo。从构造函数抛出异常可防止用户使用反射来创建第二个Foo。然后你创建一个private static final Foo字段来保存唯一的实例,并创建一个public static Foo getInstance()方法来返回它。Java规范确保只有在首次使用类时才调用构造函数。
public final class Foo {
private static class FooLoader {private static final Foo INSTANCE = new Foo();}
private Foo() {if (FooLoader.INSTANCE != null) {throw new IllegalStateException("Already instantiated");}}
public static Foo getInstance() {return FooLoader.INSTANCE;}}
由于行private static final Foo INSTANCE = new Foo();仅在实际使用类Foloader时执行,因此这会处理惰性实例化,并且保证它是线程安全的。
当您还希望能够序列化您的对象时,您需要确保反序列化不会创建副本。
public final class Foo implements Serializable {
private static final long serialVersionUID = 1L;
private static class FooLoader {private static final Foo INSTANCE = new Foo();}
private Foo() {if (FooLoader.INSTANCE != null) {throw new IllegalStateException("Already instantiated");}}
public static Foo getInstance() {return FooLoader.INSTANCE;}
@SuppressWarnings("unused")private Foo readResolve() {return FooLoader.INSTANCE;}}
public class Singleton {
private static Singleton instance = null;
static {instance = new Singleton();// do some of your instantiation stuff here}
private Singleton() {if(instance!=null) {throw new ErrorYouWant("Singleton double-instantiation, should never happen!");}}
public static getSingleton() {return instance;}
}
/*** Singleton pattern example using Java Enum*/public enum EasySingleton {INSTANCE;}
双重检查锁定/延迟加载
/*** Singleton pattern example with Double checked Locking*/public class DoubleCheckedLockingSingleton {private static volatile DoubleCheckedLockingSingleton INSTANCE;
private DoubleCheckedLockingSingleton() {}
public static DoubleCheckedLockingSingleton getInstance() {if(INSTANCE == null) {synchronized(DoubleCheckedLockingSingleton.class) {// Double checking Singleton instanceif(INSTANCE == null) {INSTANCE = new DoubleCheckedLockingSingleton();}}}return INSTANCE;}}
静态工厂方法
/*** Singleton pattern example with static factory method*/
public class Singleton {// Initialized during class loadingprivate static final Singleton INSTANCE = new Singleton();
// To prevent creating another instance of 'Singleton'private Singleton() {}
public static Singleton getSingleton() {return INSTANCE;}}
public class Foo {
// It will be our sole heroprivate static final Foo INSTANCE = new Foo();
private Foo() {if (INSTANCE != null) {// SHOUTthrow new IllegalStateException("Already instantiated");}}
public static Foo getInstance() {return INSTANCE;}}
一切都很好,除了它是一个早期加载的单例。让我们试试懒惰加载的单例
class Foo {
// Our now_null_but_going_to_be sole heroprivate static Foo INSTANCE = null;
private Foo() {if (INSTANCE != null) {// SHOUTthrow new IllegalStateException("Already instantiated");}}
public static Foo getInstance() {// Creating only when required.if (INSTANCE == null) {INSTANCE = new Foo();}return INSTANCE;}}
class Foo {
private static Foo INSTANCE = null;
// TODO Add private shouting constructor
public static Foo getInstance() {// No more tension of threadssynchronized (Foo.class) {if (INSTANCE == null) {INSTANCE = new Foo();}}return INSTANCE;}}
但仅仅保护英雄是不够的,真的!!!这是我们能/应该做的最好的事情来帮助我们的英雄:
class Foo {
// Pay attention to volatileprivate static volatile Foo INSTANCE = null;
// TODO Add private shouting constructor
public static Foo getInstance() {if (INSTANCE == null) { // Check 1synchronized (Foo.class) {if (INSTANCE == null) { // Check 2INSTANCE = new Foo();}}}return INSTANCE;}}
class Foo implements Serializable {
private static final long serialVersionUID = 1L;
private static volatile Foo INSTANCE = null;
// The rest of the things are same as above
// No more fear of serialization@SuppressWarnings("unused")private Object readResolve() {return INSTANCE;}}
public final class Foo implements Serializable {
private static final long serialVersionUID = 1L;
// Wrapped in a inner static class so that loaded only when requiredprivate static class FooLoader {
// And no more fear of threadsprivate static final Foo INSTANCE = new Foo();}
// TODO add private shouting construcor
public static Foo getInstance() {return FooLoader.INSTANCE;}
// Damn you serialization@SuppressWarnings("unused")private Foo readResolve() {return FooLoader.INSTANCE;}}
这就是我们的英雄:)
由于行private static final Foo INSTANCE = new Foo();仅在实际使用类FooLoader时执行,因此这会处理惰性实例化,并且保证它是线程安全的。
我们已经走了这么远。以下是实现我们所做的一切的最佳方式:
public enum Foo {INSTANCE;}
内部将被视为
public class Foo {
// It will be our sole heroprivate static final Foo INSTANCE = new Foo();}
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {if (INSTANCE != null)throw new IllegalStateException(“Already instantiated...”);}
public synchronized static Singleton getInstance() {return INSTANCE;}
}
public class MySingleton {private static MySingleton instance = null;private MySingleton() {}public static synchronized MySingleton getInstance() {if(instance == null) {instance = new MySingleton();}return instance;}}
延迟加载,线程安全阻塞,由于synchronized而性能低下。
版本2:
public class MySingleton {private MySingleton() {}private static class MySingletonHolder {public final static MySingleton instance = new MySingleton();}public static MySingleton getInstance() {return MySingletonHolder.instance;}}
public enum SingletonEnum {INSTANCE;public void doSomething(){System.out.println("This is a singleton");}}
此代码自Java1.5中引入枚举以来一直有效
双重检查锁定
如果你想编写一个在多线程环境中工作的“经典”单例(从Java1.5开始),你应该使用这个。
public class Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class){if (instance == null) {instance = new Singleton();}}}return instance;}}
这在1.5之前不是线程安全的,因为易失性关键字的实现不同。
早期加载单例(甚至在Java1.5之前工作)
此实现在加载类时实例化单例并提供线程安全。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {return instance;}
public void doSomething(){System.out.println("This is a singleton");}
}
public class Singleton {// It must be static and final to prevent later modificationprivate static final Singleton INSTANCE = new Singleton();/** The constructor must be private to prevent external instantiation */private Singleton(){}/** The public static method allowing to get the instance */public static Singleton getInstance() {return INSTANCE;}}
这是如何正确地懒惰创建你的单例:
public class Singleton {// The constructor must be private to prevent external instantiationprivate Singleton(){}/** The public static method allowing to get the instance */public static Singleton getInstance() {return SingletonHolder.INSTANCE;}/*** The static inner class responsible for creating your instance only on demand,* because the static fields of a class are only initialized when the class* is explicitly called and a class initialization is synchronized such that only* one thread can perform it, this rule is also applicable to inner static class* So here INSTANCE will be created only when SingletonHolder.INSTANCE* will be called*/private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}}
public class Test {private static final Test test = new Test();
private Test() {}
public static Test getTest() {return test;}}
延迟初始化单例(线程安全)
public class Test {private static volatile Test test;
private Test() {}
public static Test getTest() {if(test == null) {synchronized(Test.class) {if(test == null) {test = new Test();}}}return test;}}
带有支架模式的Bill Pugh单例(最好是最好的一个)
public class Test {
private Test() {}
private static class TestHolder {private static final Test test = new Test();}
public static Test getInstance() {return TestHolder.test;}}
枚举单例
public enum MySingleton {INSTANCE;
private MySingleton() {System.out.println("Here");}}
public class Singleton<T> implements Supplier<T> {
private boolean initialized;private Supplier<T> singletonSupplier;
public Singleton(T singletonValue) {this.singletonSupplier = () -> singletonValue;}
public Singleton(Supplier<T> supplier) {this.singletonSupplier = () -> {// The initial supplier is temporary; it will be replaced after initializationsynchronized (supplier) {if (!initialized) {T singletonValue = supplier.get();// Now that the singleton value has been initialized,// replace the blocking supplier with a non-blocking suppliersingletonSupplier = () -> singletonValue;initialized = true;}return singletonSupplier.get();}};}
@Overridepublic T get() {return singletonSupplier.get();}}