单例,一个进程空间中,一个类只能生成一个对象。
这里加了进程的概念,超出进程来讲单例,有没有意义?通常情况下是没有的。但我在扩展篇里会聊到一些特殊的单例。
最简单的实现,基本一行代码可以搞定。
V1.0
public static final SingleInstance instance = new SingleInstance(); private SingleInstance () { }
写完之后,我们可以习惯性的问自己几个问题。
1. 单线程下,它是不是只能创建一个对象?是的,由于私有的构造函数存在,其他类无法创建这个对象。
2. 效率高吗?额,好像不见得。只要加载了类,这个对象就会被创建出来。不符合延迟加载策略,有点浪费内存与时间
3.他线程安全吗?应该是的。何以见得,有图为证:
简单的说,在加载类的时候,是有同步的,防止多个线程在加载同一个类的,出现多个相同的类。
于是,优化了下。
V2.
public static volatile SingleInstance instance = null; public static SingleInstance getInstance() { if( instance == null) { synchronized (SingleInstance.class) { if( instance == null) { instance = new SingleInstance(); } } } return instance; } private SingleInstance () { }
同样的上面的问题,看起来都OK了。
有没有简单点的。
V3
public static SingleInstance getInstance() { return InstanceHolder.instance; } private SingleInstance () { } private static class InstanceHolder { public static volatile SingleInstance instance = new SingleInstance(); }
有没有更简单点的,有
V3
public enum SingleInstance { INSTANCE; private SingleInstance () { } public static SingleInstance getInstance() { return INSTANCE; } private int field1; private int field2; public void test() { } }
把class改为enum,用枚举来限制单例。
基本的单例先到这里,网上资料也很多,下次讨论一下扩展。
预告:有限制数量的单例怎么搞,带参数的又怎么搞,想要回收单例怎么办,多个进程中的单一组件怎么实现?