多线程实操&&单例模式

发布于:2022-12-22 ⋅ 阅读:(93) ⋅ 点赞:(0)

前言:

        本文将介绍多线程的实操案例——单例模式,单例模式是一种设计模式,其实操案例也细分为两种模式:懒汉模式和饿汉模式,其中也涉及静态工厂方法的使用。所以本文现简单介绍一下静态工厂方法,在进行介绍两个单例模式

一、静态工厂方法

        所谓静态工厂方法就是将创建对象封装起来,然后在方法内部将创建的对象引用返回给外界调用。可能你会问这样做又有好处?往下看,将会得到答案。

        我们一般来说创建对象都是通过使用对象构造器,也就是new一个对象。构造器可以有很多不同参数个数的同位体,并且这些构造器需要重载才能被创建出来,并且构造器名字都一样只能靠参数来进行区分,所以使用这个类的程序猿需要对这个类有一定了解才行。相同个数参数的构造器却是不能存在的,只能活一个。

        而对于实际开发中,我们可能会需要使用相同参数个数,但是是不同参数意义(类型相同)的构造器,但是显而易见这个构造器压根不可能存在,所以这个时候就需要用到我们的静态工厂方法,如下代码:

class Person{
    int age;
    int weight;
    private static Person person = null;
    private Person(){
    }
    
    //构造有年龄属性的对象
    public static Person AgeOfPerson(int age){
        person = new Person();
        person.age = age;
        return person;
    }

    //构造有体重属性的对象
    public static Person WeightOfPerson(int weight){
        person = new Person();
        person.weight = weight;
        return person;
    }
}

        上面代码就可以根据不同的工厂方法构造出想要的对象。

        【首先】工厂方法的命名都与参数有关的,这就是说明,我们能更清楚的知道这个方法的作用。相比之下,我们不需要对这个类有太多理解也能创建类对象。

        【其次】要自定义工厂方法,还需要将类构造器设置为private,防止直接创建

        【最后】工厂方法一般为类方法(静态方法),具有返回对象(返回对象的引用)

二、单例模式

        在对工厂方法有一定了解后,我们开始介绍单例模式

1.什么是单例模式

        单例模式是一种设计模式,单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例相当于处于一个被共享的位置。.

2.多线程中的单例模式

        多线程中的单例模式有两种,一种是饿汉模式,一种是懒汉模式

        为了方便理解饿汉模式和懒汉模式,我们举一个例子:

        吃饭需要用到碗筷,对于饿汉来说,他必须把碗筷在每次结束战斗后都洗一次碗,来保证饿的时候有碗吃饭,相当于提前行动。而懒汉呢?他比较懒,什么时候吃饭就什么时候洗,不吃就不洗,相当于按需行动,所以基于此,我们可以利用这“饿汉”和“懒汉”的特性构造出不同的两种单例设计模式。

1)饿汉模式

        直接上代码:

//饿汉模式
class Singleton{
    //1.线程在初始直接创建实例
    private static Singleton instance = new Singleton();
    //2.设置私有无参构造器,防止被主动创建实例
    private Singleton(){}
    //3.创建一个方法将这个对象的引用返回(静态工厂方法)
    public static Singleton getInstance(){
        return instance;
    }
}

        代码中,是提前创建好了类对象,然后等工厂方法调用就将这个引用返回,所以可以看出,getInstance方法返回的引用一直都是同一个Singleton对象 

2)懒汉模式

        相比于饿汉模式,懒汉模式又分为单线程和多线程,多线程会稍微复杂一点,因为其涉及到锁的应用

 懒汉模式——单线程

//懒汉模式--单线程
class Singleton1{
    //1.设置类变量,但是被赋值为null值,因为懒汉模式只在需要的时候才进行创建实例
    private static Singleton1 instance = null;
    //2.设置私有无参构造器,防止被主动创建实例
    private Singleton1(){}
    //3.构建返回对象实例的引用
    public static Singleton1 getInstance(){
        //判断这个对象是否实例化了,如果有就直接返回,否则先创建在返回
        if(instance == null){
            instance = new Singleton1();
        }
        return instance;
    }
}

懒汉模式——多线程

//懒汉模式--多线程
class Singleton2{
    //1.设置类变量,但是被赋值为null值,因为懒汉模式只在需要的时候才进行创建实例,加上volatile防止编译'优化'
    private static volatile Singleton2 instance = null;
    //2.设置私有无参构造器,防止被主动创建实例
    private Singleton2(){}
    //3.构建返回对象的引用方法
    public static Singleton2 getInstance(){
        //4.与懒汉单线程模式不一样的是,多线程模式需要考虑多个线程同时访问的问题,这个时候需要对对象进行上锁保护
        //5.这里上锁的设置对象用到是类对象,也就是这个类的class文件,因为这个类对象独有一份,可以被所以懒汉模式多线程都使用到,并且也符合单例模式的概念
        //6.但是如果这样简单的设置锁,也是不行的,因为假如对象已经被实例了,就没有必要设置上锁浪费不必要的实际,所以还得多上层判断,达到降低竞争锁的频率
        //synchronized(Singleton2.class){
        //    if(instance == null){
        //        instance = new Singleton2();
        //    }
        //}
        if(instance == null) {
            //7.在这里多上一层判断,虽然有两个一样的 if(instance == null) 但是效果是不一样的.
            //8.第一层就是用来判断有没有已经被实例化了,如果有就直接返回引用达到和饿汉模式一样效果,
            //如果没有就是进入锁,等一个锁完成后才到另一个线程得到锁,开始判断,但是这个时候,对象已经被实例出来的,所以第二个instance的判断为false,然后就直接返回
            synchronized (Singleton2.class) {
                if (instance == null) {
                    instance = new Singleton2();
                }
            }
        }
        return instance;
    }
}

        代码的说明已经在块里面了,请耐心看完哦~

个人笔记使用~~

本文含有隐藏内容,请 开通VIP 后查看