Java常用GoF设计模式之一单例模式
2016-10-21 16:54
375 查看
单例模式概念及特点
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例(应用比较少,不做介绍)三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例的使用场景
懒汉式单例模式一(方法加锁):
为什么用volatile可以保证线程安全参考:
单例模式与双重检测
用happen-before规则重新审视DCL
懒汉式单例模式三(静态内部类的方式):
饿汉式单例模式一(静态常量实现):
饿汉式单例模式二(枚举实现):
测试效率:
单例对象 占用资源少,不需要延时加载:
枚举式好与 饿汉式
单例对象 占用资源大,需要延时加载:
静态内部类式好于懒汉式
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例(应用比较少,不做介绍)三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例的使用场景
懒汉式单例模式一(方法加锁):
package cn.gof.singleton; /** * @author zhaopan * @date 2016年10月21日 上午10:11:01 * 单例模式--懒汉式 * 优点:实现了简单的懒加载,真正用的时候才加载。 * 缺点:方法同步,调用效率稍低 */ public class Singleton03 { private static Singleton03 singleton03; private Singleton03(){ } public static synchronized Singleton03 getInstance(){ if (singleton03==null){ singleton03=new Singleton03(); } return singleton03; } }懒汉式单例模式二(双重检测锁机制):
package cn.gof.singleton; /** * @author zhaopan * @date 2016年10月21日 上午10:27:50 * 双重检测锁机制的懒汉式 * 优点:将同步内容下放到if内部,提高了执行效率,不必每次获取对象时进行同步。 * 缺点:由于编译器优化和JVM底层内部模型原因,偶尔会出问题,不建议使用。JDK5.0以后版本若instance为volatile则可行 * * 因为这里的同步只需在第一次创建实例时才同步,一旦创建成功,以后获取实例时就不需要同获取锁了) * 但在Java中行不通,因为同步块外面的if (instance == null)可能看到已存在,但不完整的实例。 * JDK5.0以后版本若instance为volatile则可行 */ public class Singleton04 { //private static Singleton04 singleton04; private volatile static Singleton04 singleton04; private Singleton04(){ } public static Singleton04 getInstance(){ if(singleton04==null){ synchronized (Singleton04.class) { if(singleton04==null){ singleton04=new Singleton04(); } } } return singleton04; } }
为什么用volatile可以保证线程安全参考:
单例模式与双重检测
用happen-before规则重新审视DCL
懒汉式单例模式三(静态内部类的方式):
package cn.gof.singleton; /** * @author zhaopan * @date 2016年10月21日 上午10:46:40 * 静态内部类方式 实现懒汉式单例 * 优点:并发高效调用和延时加载的优势。 * 外部类没有static属性,则不会像俄汉式那样立即加载对象。 * 只有真正调用getInstance(),才会加载静态内部类。加载类时是线程安全的。 * 因为instance是static final 类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证线程安全性。 * */ public class Singleton05 { private Singleton05(){ } public static class SingletonInstance{ private static final Singleton05 SINGLETON05 =new Singleton05(); } public static Singleton05 getInstance(){ return SingletonInstance.SINGLETON05; } }
饿汉式单例模式一(静态常量实现):
package cn.gof.singleton; /** * @author zhaopan * @date 2016年10月21日 上午10:03:35 * 最简单的单例模式 饿汉式 * * 优点:static,此时不会设计多个线程对象访问该对象的问题。变量会在类加载时初始化线程安全,调用效率高 * 缺点:无法实现延迟加载,如果是加载本类,而没有使用,则会造成资源浪费。 */ public class Singleton01 { private static final Singleton01 singleton01=new Singleton01(); //私有化构造方法 private Singleton01() { } //提供公有的获取实例的方法 public static Singleton01 getInstance(){ return singleton01; } }
饿汉式单例模式二(枚举实现):
package cn.gof.singleton; /** * @author zhaopan * @date 2016年10月21日 上午10:37:48 * 枚举实现饿汉式单例模式 * 优点:1、 自由序列化;2、 保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量);3、 线程安全; * 缺点:无延时加载 */ public enum Singleton02 { INSTANCE; public void sayHi(){ System.out.println("我是枚举类型的单例"); } }
测试效率:
package cn.gof.singleton; /** * @author zhaopan * @date 2016年10月21日 下午4:57:02 * */ import java.util.concurrent.CountDownLatch; /** * 测试多线程环境下五种创建单例模式的效率 * @author liguodong * */ public class ClientTest { public static void main(String[] args) throws InterruptedException { long start = System.nanoTime(); int threadNum = 10; long sum=0; final CountDownLatch count = new CountDownLatch(threadNum); int[] ins=new int[10]; for(int j=0;j<100;j++) { for(int i=0;i<10;i++) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<1000000;i++) { /** * 饿汉式 */ // Object o = Singleton01.getInstance(); //普通饿汉式118755558---143202450 //Object o = Singleton02.INSTANCE;//枚举式的111872193---163903002 大部分是11-13 /** * 懒汉式 */ //Singleton03 instance = Singleton03.getInstance(); //方法加同步关键字2126685034 //Singleton04 instance2 = Singleton04.getInstance();//将方法内部加同步464849105 //Object o = Singleton05.getInstance(); //内部类的方式 118638630--134209601 } count.countDown(); } }).start(); } count.await();//main线程阻塞,直到计数器变为0,才会继续往下执行。 long end = System.nanoTime(); sum=sum+end-start; } System.out.println("总耗时:"+(sum/100)); } }比较两种模式?
单例对象 占用资源少,不需要延时加载:
枚举式好与 饿汉式
单例对象 占用资源大,需要延时加载:
静态内部类式好于懒汉式
相关文章推荐
- Java常用GoF设计模式之一模板模式
- Java常用GoF设计模式之一装饰者模式
- Java常用GoF设计模式之一代理模式
- GoF的设计模式是Java基础知识和J2EE框架知识之间一座隐性的"桥"
- java常用设计模式
- java常用的设计模式
- Java常用设计模式
- Java常用的设计模式
- Java常用的设计模式
- Java中常用设计模式总结
- JAVA GOF设计模式 总结。
- Java中几个常用设计模式
- JAVA常用设计模式总结
- GOF以及java的23种设计模式简介
- GOF以及java的23种设计模式简介
- GoF设计模式学习之一:单例模式(Java实现)
- java GOF设计模式--------------代理模式(Proxy Pattern)
- GOF 23种设计模式(Patterns in Java)
- java常用的设计模式
- Java常用的设计模式