自学内容网 自学内容网

工作需要了解一下单例模式

作用:减少内存占用

本质:只创建一次对象的设计模式-软件设计模式

外挂:整个程序都能共享这一单例对象

分类:

  1. 懒汉式:需要的时候才创建单例类的对象-先判断该对象是否已经实例化若已实例化直接返回该类对象。否则则先执行实例化操作。
  2. 饿汉式:在类加载时就创建好对象,后面随时调用-在编码时就已经指明了要马上创建这个对象,不需要等到被调用时再去创建。

懒汉式-双校验+锁-线程安全


public class Singleton {
    
    private static Singleton singleton;
    
    private Singleton(){}
    
    public static Singleton getInstance() {
        if (singleton == null) {  // 线程A和线程B同时看到singleton = null,如果不为null,则直接返回singleton
            synchronized(Singleton.class) { // 线程A或线程B获得该锁进行初始化
                if (singleton == null) { // 其中一个线程进入该分支,另外一个线程则不会进入该分支
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

为什么要进行两次的判断呢?

现在我们假设有两个线程a,b。两个线程都去请求我们单例模式下类的实例,

当第一个判断的时候,两个线程都会进入判断代码块中进行锁的抢占,最终a抢占到了锁,那么b只能在加锁的代码块外部进行等候,这个时候a创建了对象的实例,完成功能后归还了锁,这个时候线程b马上抢占到了锁,然后进入内部代码块

假设在这里没有第二次判断的话,线程a就会再次创建一个新的对象,所以,要在这里再加一次判断。

双重检查锁模式是一种非常好的单例实现模式,解决了单例、性能、线程安全问题,但是呢,JVM在实例化对象的时候会进行优化和指令重排序操作,在多线程的情况下,就可能会出现空指针问题

饿汉式

这种方法通过将对象的实例设置为静态的方式,保证了该对象的实例,永远只有一份,且该对象的创建在类加载的时候就会立即创建在jvm内存中的方法区,在程序运行期间永久存在,所以当我们的对象太大的时候就会造成一种资源的浪费。

/**
* 饿汉式
* 静态变量创建类的对象
*/
public class Singleton {
    //私有构造方法
    private Singleton() {}
    //在成员位置创建该类的对象
    private static Singleton instance = new Singleton();
    //对外提供静态方法获取该对象
    public static Singleton getInstance() {
        return instance;
    }
}

请多多指教


原文地址:https://blog.csdn.net/m0_63052064/article/details/144276784

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!