单例模式(Singleton)

单例模式指的是:此类在任何时候都只存在一个对象。

实现步骤:1、构造器私有化。2、提供公共的  获取对象的方法getInstance()。

分类:

    饿汉式:在加载类的时候就创建对象。

    懒汉式:在使用类的时候才创建对象。

    枚举,是 JDK 1.5 中引入的新特性。


实现方式:

1、饿汉式:在加载类的时候,便创建对象。

/**
 *饿汉式实现单例模式:加载类的时候创建好对象。不能延时加载
 */
public class Antts{
    //1、类加载的时候线程一定安全
    private static Antts instance = new Antts();

    //2、构造器私有化
    private Antts(){
        if(null!=instance) {
            throw new RuntimeException();//避免通过反射调用构造器
        }
    }
    //3、对外提供获取对象的方法
    public static Antts getInstance() {
        return instance;
    }
    //4、避免通过反序列化获取新对象
    public Object readResolve() throws ObjectStreamException{
        return instance;
    }
}
示例代码

2、懒汉式:在使用的时候,创建对象(延时加载),需要给getInstance方法加锁,慢。

/**
 *懒汉式实现单例模式:要使用对象的时候创建对象(延时加载),需要加锁。
 */
public class Antts{
    //1、类加载的时候线程一定安全
    private static Antts instance;

    //2、构造器私有化
    private Antts(){
        if(null!=instance) {
            throw new RuntimeException();//你干嘛?想通过反射创建新对象?
        }
    }
    //3、对外提供获取对象的方法,为了保证多线程下不出意外,需要加锁。
    public static synchronized Antts getInstance() {
        if(instance==null){
            instance = new Antts();//使用的时候创建对象
        }
        return instance;
    }
    //4、避免通过反序列化获取新对象
    public Object readResolve() throws ObjectStreamException{
        return instance;
    }
}
示例代码

 

3、懒汉式,但是使用静态内部类创建对象:不需要使用锁,快。

/**
 * 静态内部类实现单例:类加载的时候不会加载内部类
 */
public class Antts{
    //1、为了保证不被反射和反序列化创建多个对象,储存一下
    private static Antts instance;

    //静态内部类
    private static class Temp{
        private static final Antts antts = new Antts();
    }

    //2、构造器私有化
    private Antts(){
        if(null!=instance) {
            throw new RuntimeException();//你干嘛?想通过反射创建新对象?
        }
    }
    //3、此时才会加载内部类
    public static  Antts getInstance() {
        if(instance==null){
            instance=Temp.antts;
        }
        return instance;
    }
    //4、避免通过反序列化获取新对象
    public Object readResolve() throws ObjectStreamException{
        return instance;
    }
}
查看示例

4、懒汉式,但是使用双重检测加锁:使用了synchronized块,volatile声明,保证对象唯一。

class Antts{
    //volatile避免指令重排导致  创建多个对象
    private static volatile Antts instance;

    //构造器私有化
    private  Antts(){ 
        if(instance!=null){
            throw new RuntimeException();//你干嘛?
        }
    }
    //提供公共的静态方法获取对象
    public static Antts getInstance(){
        //双重检测,提高性能。
        if(null!=instance){
            return instance;
        }
        synchronized (Antts.class) {
            if (instance == null) {
                //创建一个对象:1、开辟空间。2、初始化对象信息。3、返回对象地址给引用。
                instance = new Antts();
            }
            return instance;
        }
    }
}
实现代码

5、枚举实现:在加载的时候就创建了,不能延时加载。(了解一下:枚举

/**
 * 使用枚举实现单例:这里的Antts.INSTANCE用于只有一个。
 */
public enum  Antts{
    INSTANCE;
    void doSomething(){
        System.out.println("I love her!");
    }
}
class test{
    public static void main(String[] args) {
        Antts.INSTANCE.doSomething();
    }
}

运行结果:

 

posted @ 2022-11-22 18:56  在博客做笔记的路人甲  阅读(154)  评论(0编辑  收藏  举报