设计模式-4-单例模式
2016-03-26 15:14
239 查看
单利模式
原理:确保一个类最多只有一个实例,并提供一个全局访问点(构造函数私有化、提供一个静态的方法获取实例)有些对象我们只需要一个:线程池、缓存、硬件设备(用静态变量的方式实现)
单例的几种实现方法
饿汉式(线程安全 在类的加载的时候就实例一个对象出来,以空间换时间,当这个类太大的时候并且没用到的时候浪费了内存)
public class EagerSingleton { //创建一个私有的EagerSingleton对象 private static EagerSingleton eagerSingleton = new EagerSingleton(); //私有的构建方法 private EagerSingleton(){}; //静态工厂方法 public static EagerSingleton getInstance(){ return eagerSingleton; } }测试
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub EagerSingleton eagerSingleton = EagerSingleton.getInstance(); System.out.println(eagerSingleton); EagerSingleton eagerSingleton1 = EagerSingleton.getInstance(); System.out.println(eagerSingleton1); } }输出相同的地址
EagerSingleton@2a139a55 EagerSingleton@2a139a55
懒汉式(加了一个同步锁解决多线程安全问题 以时间换空间 没人使用的话就不会创建实例节约了内存空间)
public class LazySingleton { private static LazySingleton lazySingleton = null; private LazySingleton(){}; //synchronized关键字:同步锁,多线程安全(当线程A正在执行lazySingleton = new LazySingleton();的时候, //在这个时候刚好有一个线程B执行到if(lazySingleton==null 那么就会执行,这样就实例的两个) //缺点:同步锁消耗的资源挺多的 public static synchronized LazySingleton getInstance(){ if(lazySingleton==null){ lazySingleton = new LazySingleton(); } return lazySingleton; } }测试
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub LazySingleton lazySingleton = LazySingleton.getInstance(); System.out.println(lazySingleton); LazySingleton lazySingleton1 = LazySingleton.getInstance(); System.out.println(lazySingleton1); } }输出相同的地址
LazySingleton@2a139a55 LazySingleton@2a139a55
双重检查加锁(缺点:运行效率不高,不建议使用)
volatile关键字:所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量public class Singleton { private static volatile Singleton singleton = null; private Singleton(){}; public static Singleton getInstance(){ //先检查实例是否存在,不存在才进入下面的同步块 if(singleton==null){ //同步块,线程安全的创建实例 synchronized (Singleton.class) { //再次检查实例是否存在,不存在才真正的创建实例 if(singleton==null) singleton = new Singleton(); } } return singleton; } }检查
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Singleton singleton = Singleton.getInstance(); System.out.println(singleton); Singleton singleton1 = Singleton.getInstance(); System.out.println(singleton1); } }
输出相同的地址
LazySingleton@2a139a55 LazySingleton@2a139a55
Lazy initialization holder class 模式
<pre name="code" class="html">public class Holder { //构建函数 private Holder(){}; //类级内部类 private static class SingHolder{ private static Holder holder = new Holder(); } //通过Holder.getInstance然后调用SingHolder.holder实例化对象 public static Holder getInstance(){ return SingHolder.holder; } }
测试
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Holder holder = Holder.getInstance(); System.out.println(holder); Holder holder1 = Holder.getInstance(); System.out.println(holder1); } }
输出相同的地址
LazySingleton@2a139a55 LazySingleton@2a139a55
枚举(最佳实现单例的方法)
public enum Singleton { INSTANCE;//唯一实例 public static Singleton getInstance(){ return INSTANCE; } }测试
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Singleton enum1 = Singleton.getInstance(); System.out.println(enum1); Singleton enum2 = Singleton.getInstance(); System.out.println(enum2); } }输出一样的结果
INSTANCE INSTANCE
总结:
枚举的单例简单方便,但是使用的话自己还是有一些疑问的,所以自己用的话一般选择 Lazy initialization holder class 模式(个人爱好啦~)相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用
- 深入解析C#设计模式编程中对建造者模式的运用