设计模式学习笔记:单例模式

1、概念

通常采用单例模式就是为了知足“只建立一个类”的须要。安全

单例模式有两个特色:
(1)一个类仅有一个实例
(2)仅有一个全局访问点线程

2、写法

一、饿汉式
所谓饿汉式,是指这个类的实例在类加载阶段就已经建立出来了。code

public class Singleton1 {
    //在类的内部实例化一个实例
    private static final Singleton1 instance = new Singleton1();
    //隐藏构造方法
    private Singleton1() {
    }
    //对外开放一个获取实例的方法
    public static  Singleton1 getInstance(){
        return instance;
    }
}

固然也可使用static代码块。(注意这里的final,看网上有各类写法,加或者不加的都有,我认为这里能够加,这样getInstance方法里就不须要判空了)对象

这种方式虽然可以有效避免线程安全的问题,可是却可能形成没必要要的浪费,由于也许这个实例并不须要用到,或者就用到一两次,却要一直占用内存。内存

二、静态内部类get

public class InnerClassSingleton {
    //在静态内部类中实例化对象
    private static class SingletonHolder{
        private static final InnerClassSingleton instance = new InnerClassSingleton();
    }
    //隐藏构造方法
    private InnerClassSingleton(){
    }
    //对外提供访问方法
    public static final InnerClassSingleton getInstance() {
        return SingletonHolder.instance;
    }
}

三、懒汉式
所谓懒汉式,就是在使用时才加载,比较“懒一些”。class

public class Singleton2 {
    private static Singleton2 instance;
    private Singleton2(){
    }
    public static Singleton2 getInstance(){
        //在对象被使用时才实例化
        if (instance == null)
            instance = new Singleton2();
        return instance;
    }
}

注意:加上synchronized关键字就能够保证线程安全。效率

public class Singleton2 {
    private static Singleton2 instance;
    private Singleton2(){
    }
    public static synchronized Singleton2 getInstance(){
        //在对象被使用时才实例化
        if (instance == null)
            instance = new Singleton2();
        return instance;
    }
}

四、固然上述方式效率比较低,由于synchronized锁的范围太大了程序

public class Singleton2 {
    private static Singleton2 instance;
    private Singleton2(){
    }
    public static Singleton2 getInstance(){
        //在对象被使用时才实例化
        synchronized (Singleton2.class){
            if (instance == null)
                instance = new Singleton2();
            return instance;
        }
    }
}

这样就缩小了锁的范围,可是这种方式依然存在问题,由于Java内存模型的机制,程序可能会崩溃,所以就要用到volatile。方法

五、使用volatile

public class Singleton2 {
    private static volatile Singleton2 instance;
    private Singleton2(){
    }
    public static Singleton2 getInstance(){
        //在对象被使用时才实例化
        if (instance == null){
            synchronized (Singleton2.class){
                if (instance == null)
                    instance = new Singleton2();
                return instance;
            }
        }
    }
}

六、枚举式

public enum  Singleton3 {
    INSTANCE;
    Singleton() {
    }
}
相关文章
相关标签/搜索