java设计模式之单例模式5种方法及优缺点小结
2017-06-04 18:27
387 查看
单例设计模式的用处。
单例设计模式是指,某个类只有一个实例。在计算机系统中类似于打印机和最常见的就是任务管理器的对话框,不管几个用户同时登录windows 打开的任务对话框只有一个。
常见的几种实现方式:
1.lazy-load
/* 适合单线程模式 延迟加载 lazy-load*/ public class Singleton { /* 私有的静态对象变量,来标记是否初始化过 也用来把实例化进行缓存*/ private static Singleton instance = null; /* 私有的构造函数防止外部调用 */ private Singleton (){} /* 供外部调用的接口是public的其余均为private */ public static Singleton getInstance(){ /* 单线程模式先如果对象变量为空,那么需要创建 */ /* 但是多线程下这个地方需要同步,否则会出现两个线程都创建了一个实例的情况 */ if(instance == null){ instance = new Singleton(); } return instance; } }
2.lazy-load的变种1线程安全了但是效率很差
/* 多线程下可以使用但是如果两个线程同时想创建实例的化,加锁和等待锁是很耗时的 如果不想创建实例了但是还要获取锁,这样很不好。 lazy-load */ public class Singleton{ private static Singleton instance = null; private Singleton(){ } public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
3,lazy-load的变种2线程安全了,效率有提高
/* 对上一种方式进行了优化,提前判断一下变量是否为空,前后两次判断是否存在 lazy-load */ /* 但是这种两次if判断的存在出错的情况 */ /* */ public class Singleton{ /* 此处使用volatile关键字 */ private volatile static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ /* 第一次判断 隔绝在已经实例之后调用get接口获取实例对象的情况,放置这些情况仍然调用锁 */ if(instance == null){ /* 防止两个线程同时进行创建实例 */ synchronized(Singleton.class){ /* 这个if判断也是必须的,如果出现了两个线程同时等待锁,但是第一个线程释放之后,第二个线程进入但是却没有判断锁是否释放的化,那么仍然是创建了两次,同时这个instance也一定是volatile 的保证可见性 */ if(instance == null){ instance = new Singleton(); } } } return instance; } }
但是这样的doubleif仍然有问题。虽然使用了volatile 虽然两次if判断。
因为无序写入:
这个double if 判断的参考了这个写的特别好,值得学习
引申:
4.饿汉式
/* 饿汉式,类加载就会创建实例而不去管你用不用, 但是内存使用率低 线程安全。因为虚拟机保证了类只会加载一次,在装载类的时候是不会并发的 */ public class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } }
5.静态内部类
/* 静态内部类 */ /* 由于内部类不会在加载外部类的时候进行加载,那么这个也属于lazy-load。但是这种延迟加载的加载也是class的加载jvm保证只有一次所以同样线程安全 */ public class Singleton{ private Singleton(){} private static class SingletonIneerClass{ private final static Singleton instance = new Singleton(); } public static Singleton getInstance(){ return SingletonIneerClass.instance(); } }
相关文章推荐
- Java 单例设计模式的5种写法及优缺点
- JAVA设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
- 深入浅出Java模式设计之模板方法模式
- Java设计模式之工厂方法模式
- Java模式设计之模板方法模式
- Java设计模式—模板方法(Template Method)
- 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
- 设计模式之Factory,Java工厂方法
- Java设计模式之二 —— 工厂方法
- 3.23种设计模式的Java版--Factory Method(工厂方法)
- Java设计模式 Design Pattern:模板方法 Template Method
- 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
- 追MM与设计模式的JAVA实现-简单工厂方法
- Java设计模式(2) -- 工厂方法
- Java设计模式—模板方法(Template Method)
- JAVA设计模式——工厂方法(Factory Method)模式
- Java设计模式之工厂方法模式
- 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
- 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别【转】
- java 设计模式 学习笔记(9) 模板方法模式