欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

什么是单例模式(Singleton)?有哪几种线程安全的实现方式?

程序员文章站 2022-03-07 18:07:00
...

世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。

  1. 意图
    保证一个类仅有一个实例,并提供一个访问它的全局访问点。节省内存。用途:计数器,全局唯一ID、连接等。
  2. 类图
    什么是单例模式(Singleton)?有哪几种线程安全的实现方式?
  3. 实例
  • 实例中只展示线程安全的实现方式
// 第一种,并且是最好的实现方式,枚举,饿汉式
enum Single1{
    SINGLETON;
    public void sayHello(){
        System.out.println("enum say hello");
    }
}

// 第二种,常规饿汉式
class Single2{
    private Single2(){}
    private static final Single2 SINGLE = new Single2();
    public static Single2 getInstance(){
        return SINGLE;
    }
    public void sayHello(){
        System.out.println("饿汉式 say hello");
    }
}

// 第三种,静态内部类,懒汉式,懒汉式首选
class Single3{
    private Single3(){}
    private static class SingleHolder{
        private static final Single3 SNGLE = new Single3();
    }
    public static Single3 getInstance(){
        return SingleHolder.SNGLE;
    }
    public void sayHello(){
        System.out.println("inner static say hello");
    }
}

// 双重校验锁, 懒汉式
class Single4{
    private Single4(){}
    private static Single4 single4;
    public static Single4 getInstance(){
        if(null == single4){
            synchronized (Single4.class){
                if(null == single4){
                    return new Single4();
                }
            }
        }
        return single4;
    }
    public void sayHello(){
        System.out.println("double judge say hello");
    }
}

// 直接加锁,懒汉式,效率最低
class Single5{
    private Single5(){}
    private static Single5 single5;
    public static synchronized Single5 getInstance(){
        if(null == single5){
            return new Single5();
        }
        return single5;
    }
    public void sayHello(){
        System.out.println("normal sync lazy say hello");
    }
}
  1. 测试
class TestSingleton{
    public static void main(String[] args) {
        Single1.SINGLETON.sayHello();
        Single2.getInstance().sayHello();
        Single3.getInstance().sayHello();
        Single4.getInstance().sayHello();
        Single5.getInstance().sayHello();
    }
}

运行结果:

enum say hello
饿汉式 say hello
inner static say hello
double judge say hello
normal sync lazy say hello

想看更多吗?请访问:设计模式