|
|
|
|
优点:多线程问题解决
缺点:newInstance 阻塞
|
|
优点:性能提升,不会再newInstance阻塞。
缺点:线程安全有问题,new Singleton3()在指令重排序的情况下,可能只生成了半个对象。
详解
|
|
优点:线程安全解决,性能可行,推荐
缺点:写起来麻烦。
|
|
优点:写起来简单,线程安全(classload)机制保证。
缺点:在Singleton5被加载时 实例就已经被初始化了。1234private static Singleton5 singleton = null;static { singleton = new Singleton5();}
同理
|
|
优点:写法简单清晰,线程安全,effective java隆重推荐,不会因为序列化和反序列话新增对象
缺点:不能实现懒加载
|
|
优点:间接实现了懒加载,因为在singleton加载的时候,SingletonHolder并不会被实例化。
实现方式 | 关键点 | 资源浪费 | 线程安全 | 多线程环境的性能足够优化 |
---|---|---|---|---|
基础饱汉 | 懒加载 | 否 | 否 | - |
饱汉变种1 | 懒加载、同步 | 否 | 是 | 否 |
饱汉变种2 | 懒加载、DCL | 否 | 否 | - |
饱汉变种3 | 懒加载、DCL、volatile | 否 | 是 | 是 |
饿汉 | 静态变量初始化 | 是 | 是 | 是 |
Holder | 静态变量初始化、holder | 否 | 是 | 是 |
枚举 | 枚举本质、静态变量初始化 | 否 | 是 | 是 |
参考
- 如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些servlet容器对每个servlet使用完全不同的类装载器,这样的话如果有两个servlet访问一个单例类,它们就都会有各自的实例。
|
|
- 如果Singleton实现了java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。不管怎样,如果你序列化一个单例类的对象,接下来复原多个那个对象,那你就会有多个单例类的实例。
|
|