单例模式

Posted zzlcome

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式相关的知识,希望对你有一定的参考价值。

懒汉式

//加载该类没有创建实例,调用该类创建有且仅有一个实例
public class LazySingleton 

    //volatile:禁止cpu对字节码指令重排序
    //需要volatile关键字修饰Intance,volatile的语义是“禁止CPU对字节码指令重排序”,因为现在电脑是多核,
    //所以JVM在运行的时候会将字节码指令进行重排序优化来更好的执行,所以这就可能会出现线程A的字节码指令执行到一半,
   //线程B的字节码指令就去执行而首先对Intance进行修改,而导致线程A字节码执行到new的时候Intance已经被初始化。这时候就会有问题,所以需要禁止字节码重排序。
    private static volatile LazySingleton ls = null;
    private LazySingleton()//避免外部实例
    public static synchronized LazySingleton getInstance()//每次访问都会同步,影响性能
        if(ls == null)
            ls = new LazySingleton();
        
        return ls;
    

 

//双重检查加锁(double-checked locking),仅一次同步
public class LazySingleton2
    
    private static volatile LazySingleton2 ls2 = null;
    private LazySingleton2()//避免外部实例
    public static LazySingleton2 getInstance()
        if(ls2 == null)
            synchronized(LazySingleton2.class)//仅一次同步 
                ls2 = new LazySingleton2();
            
        
        return ls2;
    
    

 

饿汉式(推荐)

//加载该类即实例化该对象,自己创建自己
public class HungarySingleton 

    private static final HungarySingleton hs = new HungarySingleton();
    private HungarySingleton()
    private static HungarySingleton getInstance()
        return hs;
    

final修饰,仅有一个实例,所以线程安全的,可直接用于多线程。

 

静态内部类

//静态内部类
//静态内部类,作为类的成员只有该类可以访问(其他类调用该类才可以访问,保证了内部类的成员不被其他类直接调用)
public class StaticSingleton
    private static class StaticClassLazy//私有属性
        private static final StaticSingleton self = new StaticSingleton();//静态私有,只有该类可以调用
    
    private StaticSingleton()//避免外部实例
    public static final StaticSingleton getInstance()
        return StaticClassLazy.self;//自己的内部成员 调用 它的私有属性
    
    

 

枚举

//参考枚举如何实例化
enum enumSingleton
    es;
    public void doOther()
        
    

 

容器

public class containerSingleton
    private static Map<String,Object> container = new HashMap<String,Object>();//容器,其实是分配的一小块内存
    private containerSingleton()
    
//    public static Map<String, Object> getContainer() 
//        return container;
//    
//    public static void setContainer(Map<String, Object> container) 
//        containerSingleton.container = container;
//    
    //将set方法改造成注册spring中的bean(模拟)
    public static void registBean(String beanName,Object o) 
        if(!container.containsKey(beanName))
            container.put(beanName, o);//将bean的名称注入到spring容器,o可以看做bean的实例
        
    
    
    //从容器中获取已注册的bean
    public static Object getBean(String beanName) 
        return container.get(beanName);
    

以上是关于单例模式的主要内容,如果未能解决你的问题,请参考以下文章

单例模式(单例设计模式)详解

Java模式设计之单例模式(二)

单例模式(饿汉式单例模式与懒汉式单例模式)

单例模式

单例模式

设计模式之单例模式