设计模式—单例模式分析
来源:互联网 发布:在线报名系统 php 编辑:程序博客网 时间:2024/05/21 12:42
单例模式:一个类只能有一个实例
首先,一个类要想只有一个实例,构造函数必须是私有的(如果是共有的,那就谁都可以实例化了)。其次因为构造函数是私有的,如果想外部调用这个类的话,必须要存在一个公有的静态方法。还有为了保证公有的方法返回实例的过程中实例的唯一性,这个实例应该是静态的。
总结一下就是,单例模式有以下三个要素:
- 私有的构造方法
- 指向自己实例的私有静态引用
- 以自己实例为返回值的静态的公有的方法
单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例。饿汉式单例在单例类被加载时候,就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象。代码如下:
接下来来看几个网上的小例子
饿汉模式
饿汉模式—例子一:
public class Singleton {private static Singleton singleton = new Singleton();private Singleton(){}public static Singleton getInstance(){return singleton;}}
懒汉模式
懒汉模式—例子一:
public class LazyUnsafeSingleton { private volatile static LazyUnsafeSingleton instance; private LazyUnsafeSingleton() { } public static LazyUnsafeSingleton getInstance() { if (null == instance) { instance = new LazyUnsafeSingleton(); } return instance; }}
例子一很显然在多线程下操作时不行的。当多个线程同时进入静态方法时就可能会出现多个实例。针对此修改得到例子二
public class LazyMethodSynSingleton { private static LazyMethodSynSingleton instance; private LazyMethodSynSingleton() { Logger.getGlobal().info("LazyMethodSynSingleton.LazyMethodSynSingleton()"); } public static synchronized LazyMethodSynSingleton getInstance() { if (null == instance) { instance = new LazyMethodSynSingleton(); } return instance; }}例子二采用方法同步,当执行静态方法的时候把这个操作定义为原子操作,来防止多线程调用,来实现一个实例。
懒汉模式—例子三:
采用方法同步一个不好的地方就是阻塞的时间太多了,为此将同步操作定义在方法里面,进行双重校验,只有当实例为空的时候执行同步,并且为了为了防止在外层校验的时候其他现成的干扰,内层同步部分又进行一次校验。
public class LazyDoubleCheckSingleton { private volatile static LazyDoubleCheckSingleton instance; private LazyDoubleCheckSingleton() { Logger.getGlobal().info("LazyDoubleCheckSingleton.LazyDoubleCheckSingleton()"); } public static LazyDoubleCheckSingleton getInstance() { if (null == instance) { synchronized (LazyDoubleCheckSingleton.class) { if (null == instance) { instance = new LazyDoubleCheckSingleton(); } } } return instance; }}
例子三可以达到想要的效果,但是有点繁琐,利用JVM类加载机制,可以对例子三进行优化,得到例子四。
public class LazyHolderSingleton { private static class InstanceHolder { private static final LazyHolderSingleton INSTANCE = new LazyHolderSingleton(); } private LazyHolderSingleton() { Logger.getGlobal().info("LazyHolderSingleton.LazyHOlderSingleton()"); } public static LazyHolderSingleton getInstance() { return InstanceHolder.INSTANCE; }}
0 0
- 设计模式—单例模式分析
- 粗糙分析设计模式——单例模式
- Java 设计模式情景分析 ——单例模式
- 设计模式—单例设计模式
- 单例设计模式深入浅出分析
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 设计模式——单例模式
- 对人脸检测训练样本如何生成正样本描述文件和负样本集合文件
- FileStream类
- BZOJ 1116: [POI2008]CLO
- 关于Android中的乱码
- 黄斤德:金价千二上方如履薄冰,耶伦携重磅数据登场
- 设计模式—单例模式分析
- scanf,sscanf高级用法
- Cursor 的用法
- Linux初探
- 查询无结果时显示查无数据图片
- [示例总结]PicDecor实践总结
- java包装类的比较、hash和CollectionUtils交集原理探究
- ngrok
- IOS 锅鸡滑