Java笔记(三)Java中的单例模式

单例设计模式


 

何为单例模式?

简单来说,单例模式就是,一个类只允许一个实例化对象存在。

很多时候我们在整个程序或整个系统中,需要一个全局对象,此类中保存了一些在各个地方都能使用的一些配置信息,以此来看,单例设计模式就显得尤其重要了,我们不可能每次想看配置信息的时候都要创建实例化对象,那么太耗资源。

1、第一版单例设计模式

 1 class Singleton {
 2     //创建私有无参构造方法
 3     private Singleton () {};
 4     //创建私有属性,初始设置为null;
 5     private static  Singleton singleton = null;
 6     //创建获取对象的方法,静态工厂方法
 7     public static Singleton getSingleton () {
 8         //判断若是testb还是为null,那么创建对象,否则返回singleton对象
 9         if (singleton == null) {
10             singleton = new Singleton();
11         }
12         return singleton;
13     }
14 }

此段代码能实现单例模式,但是存在线程安全问题;

我们假设,在类刚刚被初始化,singleton对象还是空的,这时候有两个线程同时访问了getSingleton方法,那么就会创建出来两个对象,因为两个线程同时进行了if判断,而且两个线程是互不干扰的。

2、第二版单例设计模式

class Singleton {
    //创建静态无参构造方法
    private Singleton (){}
    //定义私有的静态的属性
    private static Singleton singleton =  null;
    //创建静态公开的工厂方法
    public static Singleton getTestC () {
        //判断属性是否为空
        //1
        if (singleton == null) {
            //加同步锁
            //2
            synchronized (Singleton.class) {
                //3
                if (singleton == null) {//双重校验
                    //4
                    singleton = new Singleton();
                }
            }
        }
        return singleton;//返回对象
    }
}

我们在1处,首先判断singleton是否为空,如果是第一次初始化实例对象肯定是空的,接着来到2,为了保证线程安全问题我们对类加了同步锁,此时就算来了两个线程,那也得老老实实的一个个排队走,接着在3处我们又进行了判断,假设有两个线程,那么第一个线程来到第3步要进行判断,为空,那么接着往下走,我们再回到第二个线程,也来到第3步就行判断,这时候就不是空了,直接return对象,因为第一个线程已经创建了对象,第二个判断肯定是为false的,那么就直接return singleton了。以此来实现了既保证线程安全又实现了单例设计模式。

在单例设计模式中有饿汉式和懒汉式的区分

饿汉式:

饿汉式的代码:

 1 class Singleton {
 2     //创建属性,直接创建实例化对象
 3     private static Singleton singleton = new Singleton();
 4     //创建私有构造方法
 5     private Singleton () {}
 6     //创建静态工厂方法,获取对象的方法
 7     public static Singleton getInstance() {
 8         return  singleton;
 9     }
10 }

在此代码中,代码在进行类加载的时候,就直接为类的属性赋值,也就是在类加载的时候直接实例化对象,创建一个对象出来,这样当我们调用getInstance的时候,就能直接获取到对象,我们知道java中的类加载,只会在初始化类的时候才会进行一次,这样无论我们调用了多少次静态方法,都只是创建了一个对象出来,以此来实现了单例模式。

饿汉式的优点是,不存在线程安全的问题,因为在类加载的时候就直接实例化对象了。

缺点:可能会造成内存的浪费,因为在类加载的时候就完成了实例化,没有就行延迟加载,如果从始至终都没有用此对象,就浪费了内存资源。

懒汉式

上面写的就是懒汉式

优点:懒汉式是什么时候使用此对象的时候,才创建,如果从始至终都没有使用该对象,就不会创建,避免了资源的浪费

缺点:会有线程同步的问题,造成线程不安全。

 

posted @ 2021-05-11 14:17  多来香菜不要葱  阅读(83)  评论(0)    收藏  举报