单例模式-----你学会了吗?

是什么----简单讲单例模式是保证运行程序中某个类的对象只有一个存在。

为什么----对于某些程序中需要频繁创建和销毁的对象,使用单例模式可以既保证程序中只有一个实例存在又可以减免不断创建和销毁对象所带的资源消耗。

    常见的应用:数据库连接池的实现,Spring中的对象默认也是单例,日志 管理,配置文件读取,SpringMVC中核心控制器

怎么做----1、构造器私有化

     2、实例内部构建

     3、提供一个public方法来获取实例

五种实现:

  1、饿汉式

  2、懒汉式

  3、双重检测锁

  4、静态内部类

  5、枚举

下面我们逐一介绍:

饿汉式

  优点:线程安全,效率高

  缺点:没能实现延时加载

package com.carter.demo01;
/**
 * 测试饿汉式
 * 1:提供一个私有静态变量
 * 2:构造方法私有化
 * 3:提供一个静态得公共访问入口
 * @author Administrator
 *
 */
public class SingletonDemo01 {
    private static SingletonDemo01 instance = new SingletonDemo01();    //类加载时被初始化,不能实现延时加载
    private SingletonDemo01(){
         
    }
    public static SingletonDemo01 getInstance(){
         return instance;
    }
}

懒汉式

优点:实现延时加载

缺点:多线程情况下需要同步,效率较低

package com.carter.demo01;
/**
 * 
 * 优点:实现延时加载,实现同步
 * 缺点:效率较低
 * @author Administrator
 *
 */
public class singletonDemo02 {
    private static singletonDemo02 instance= null;//类加载时不进行初始化,实现延时加载
    private singletonDemo02(){}
    public static synchronized singletonDemo02 getInstance(){//同步,效率低
         if(instance==null){
             instance = new singletonDemo02();
         }
         return instance;
    }
}

双重检查模式

优点:在懒汉式的思想上优化(在初始化对象时同步,提高了效率)

问题:在虚拟机内部优化时会进行指令重排可能会出现问题

解决:引入volatile(关于volatile请参考https://www.cnblogs.com/zhengbin/p/5654805.html)


/**
 * 双重检查锁(不带volatile)
 * 优点:实现延时加载,实现同步
 * 缺点:存在指令重排问题
 * @author Administrator
 *
 */

public class SingletonDemo {
private volatile static SingletonDemo instance;
    private SingletonDemo(){
    }
    public static SingletonDemo getInstance(){
        if(instance==null){
            synchronized (SingletonDemo.class){    //只有在初始化操作时进行同步
                if(instance==null){
                    instance=new SingletonDemo();
                }
            }
        }
        return instance;
    }
}

双重检查带volatile解决指令重排问题:

public class Singleton {  
    private static volatile Singleton instance;  //对对象加volatile,保证不会被指令重排
  
    private Singleton() {  
    }  
  
    public static Singleton getInstance() {  
        if (instance == null) {  
            synchronized (Singleton.class) {  
                if (instance == null) {  
                    instance = new Singleton();  
                }  
            }  
        }  
        return instance;  
    }  
} 

静态内部类

优点:线程安全,延时加载,效率高

/**
 * 测试静态内部类实现单例模式
 * 线程安全 延时加载 调用效率高
 * @author Administrator
 *
 */
public class SingletonDemo03 {
    private static class SingletonDemo{
         private static final SingletonDemo03 INSTANCE = new SingletonDemo03();
    }
    
    private SingletonDemo03(){}
   
    public static SingletonDemo03 getInstance(){
    return SingletonDemo.INSTANCE;
    }
}

枚举:

优点:线程安全,效率高,天然避开序列化和放射破解带来的问题

/**
 * 枚举实现,天然避开放射和反序例化的漏洞
 * 枚举也是类的一种
 * @author Administrator
 *
 */
public enum SingletonDemo05 {
    INSTANCE;
    
    public void getname(){
         //自身操作
    }
}

 

posted @ 2018-03-13 13:00  只要出发、就会到达  阅读(113)  评论(0)    收藏  举报