Java 单例模式 五种常见的写法
来源:互联网 发布:轨道交通大数据平台 编辑:程序博客网 时间:2024/05/01 07:42
Java 单例模式 五种常见的写法
懒汉
/** * 懒汉,线程不安全 * 由私有构造器和一个公有静态工厂方法构成,在工厂方法中对singleton进行null判断,如果是null就new一个出来,最后返回singleton对象 * 这种方法可以实现延时加载(lazy landing),但是有一个致命弱点:线程不安全。如果有两条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。 * Created by gongzi on 2017/2/13. */public class LazySingleton { private static LazySingleton instance; private LazySingleton() { } public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; }}
饿汉
/** * 饿汉法就是在第一次引用该类的时候就创建对象实例,而不管实际是否需要创建 * 好处是编写简单,但是无法做到延迟创建对象 * Created by gongzi on 2017/2/13. */public class HungerSingleton { private static HungerSingleton instance = new HungerSingleton(); private HungerSingleton() { } public static HungerSingleton getInstance() { return instance; }}
双重校验锁
/** * 双重检查锁定 * 这种写法考虑了线程安全,将对singleton的null判断以及new的部分使用synchronized进行加锁。 * 同时,对singleton对象使用volatile关键字进行限制,保证其对所有线程的可见性,并且禁止对其进行指令重排序优化。 * 在单例中new的情况非常少,绝大多数都是可以并行的读操作。因此在加锁前多进行一次null检查就可以减少绝大多数的加锁操作,执行效率提高的目的也就达到了 * 注意:双重检查锁法,不能在jdk1.5之前使用, * 而在Android平台上使用就比较放心了,一般Android都是jdk1.6以上,不仅修正了volatile的语义问题,还加入了不少锁优化,使得多线程同步的开销降低不少 * Created by gongzi on 2017/2/13. */public class DoubleValidateSingleton { private volatile static DoubleValidateSingleton singleton; private DoubleValidateSingleton() { } public static DoubleValidateSingleton getSingleton() { if (singleton == null) { synchronized (DoubleValidateSingleton.class) { if (singleton == null) { singleton = new DoubleValidateSingleton(); } } } return singleton; }}
枚举
/** * 这种方式是[Effective Java - Joshua Bloch](https://www.amazon.cn/dp/B01DPUXUWG/ref=sr_1_2?ie=UTF8&qid=1486966767&sr=8-2&keywords=Effective+Java)提倡的方式, * 使用枚举,除了线程安全和防止反射强行调用构造器之外,还提供了自动序列化机制,防止反序列化的时候创建新的对象。 * 因此,Effective Java 推荐尽可能地使用枚举来实现单例。 * 注意:枚举,虽然Effective Java中推荐使用,但是在Android平台上却是不被推荐的。 * <p> * Created by gongzi on 2017/2/13. */public enum EnumSingleton { INSTANCE; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}
静态内部类
/** * 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟第三种和第四种方式不同的是(很细微的差别): * 第三种和第四种方式是只要Singleton类被装载了,那么instance就会被实例化(没有达到lazy loading效果), * 而这种方式是Singleton类被装载了,instance不一定被初始化。 * 因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。 * 想象一下,如果实例化instance很消耗资源,我想让他延迟加载,另外一方面,我不希望在Singleton类加载时就实例化, * 因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。 * 这个时候,这种方式相比第三和第四种方式就显得很合理。 * Created by gongzi on 2017/2/13. */public class StaticInnerClassSingleton { private StaticInnerClassSingleton() { } public static final StaticInnerClassSingleton getInstance() { return SingletonHolder.INSTANCE; } private static class SingletonHolder { private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton(); }}
参考资料
- 你真的会写单例模式吗——Java实现
- http://cantellow.iteye.com/blog/838473
- 《Effective Java(第二版)》
- 《深入理解Java虚拟机——JVM高级特性与最佳实践(第二版)》
- Java:单例模式的七种写法
1 0
- Java 单例模式 五种常见的写法
- 单例模式的五种写法
- 单例模式的五种写法
- 单例模式的五种写法
- 单例模式的两种常见写法
- 单例模式的三种常见写法
- 单例设计模式的五种写法
- C# 单例模式的五种写法
- 单例模式五种写法
- 单例模式的七种写法(实际五种写法)
- 单例常见的几种写法
- java 单例模式的写法
- Java单例模式的写法
- Java单例模式的写法
- Java 的单例模式写法
- Java 单例模式的写法
- C++中几种常见的单例模式写法。
- 设计模式之单例模式的几种常见写法
- Java集合系列(2)--ArrayList
- Java.eclipse启动报错java.lang.IllegalStateException: LifecycleProcessor
- Gstreamer插件教程2.6—编写一个插件(Writing a Plugin):状态是什么?(What are states?)
- linux常用命令总结
- OpenCV for Android打开相机
- Java 单例模式 五种常见的写法
- 城市列表简称JSON数据
- jdk9的新特性
- 获取checkbox的值传给后台
- 中医行业与软件行业的职业发展比较
- 方法的重载与重写
- 题目1480:最大上升子序列和
- C++接口继承与实现继承的区别和选择
- 最短子数组