单例模式

传统的单例模式大致可以分为饿汉式与懒汉式两种形式,其区别为:

  • 饿汉式会提前将该类创建好
  • 懒汉式在第一次调用的时候创建

但是传统的单例模式在多线程下是有线程安全问题的,在方法体上采用synchronized虽然可以解决问题,但是过于笨重,因此通常采用双重校验锁来保证线程安全。

public class SingletonDemo {

    public static void main(String[] args) {
        //并发1000个线程查看效果
        for (int i = 0; i < 1000; i++) {
            new Thread(()->{
               Singleton.getInstance();
            }).start();
        }
    }
}

class Singleton{
    //volatile关键字需要加上,因为创建对象在底层可能会出现指令重排问题而导致单例失效,虽然出现的机率比较低
    private static volatile Singleton instance = null;

    private Singleton(){
        //对象被创建的时候将会输出
        System.out.println(Thread.currentThread().getName()+"new了");
    }

    //创建实例
    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                if(instance == null){
                    return instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

程序执行结果

发现1000个线程并发执行时,对象只被创建了一次。
注:双重校验锁单例模式还是可以通过反射来破坏,可以采用enum来创建单例模式,枚举模式无法通过反射创建

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容