23种设计模式_MODE01单例模式_手写代码实现

23种设计模式_MODE01单例模式_手写代码实现_第1张图片

1. 单例模式测试类SingletonTest

package com.zhaoshuangjian.mode01_单例模式;

import com.zhaoshuangjian.mode01_单例模式.mode01.Singleton1;
import com.zhaoshuangjian.mode01_单例模式.mode01.Singleton2;
import com.zhaoshuangjian.mode01_单例模式.mode01.Singleton3;
import com.zhaoshuangjian.mode01_单例模式.mode01.Singleton4;

/**
 * SingletonTest 手写代码实现单例模式
 *
 * @Auther: zhaoshuangjian  2023-03-23 下午1:07
 */
public class SingletonTest {

    public static void main(String[] args) {
        // 1、单例模式 -- 非线程安全
        Singleton1 singleton1 = Singleton1.getInstance();
        singleton1.show();

        System.out.println("==================分割线==================");

        // 2、单例模式 -- 线程安全,每次获取对象,都对当前的对象加锁
        Singleton2 singleton2 = Singleton2.getInstance();
        singleton2.show();

        System.out.println("==================分割线==================");

        // 3、单例模式 -- 线程安全,只在第一次创建实例对象的时候加锁(推荐)
        Singleton3 singleton3 = Singleton3.getInstance();
        singleton3.show();

        System.out.println("==================分割线==================");

        // 4、单例模式 -- 内部静态工厂类提前创建好实例,JVM保证instance只创建一次,且线程安全(推荐)
        Singleton4 singleton4 = Singleton4.getInstance();
        singleton4.show();

        /**
         * 以上四种单例模式,没有一种是十全十美的
         * 就拿最后一种来说,通过内部类机制达到了线程安全且实例只被创建一次,这些都是JVM帮我们实现的,我们无需关心
         * 但是,如果内部类自己的构造函数出现了问题,而不是在创建instance实例的时候出现了问题
         * 这时候,我们试想一下,我们外部还能顺利拿到单例对象吗?答案是肯定不行
         * 虽然这无疑会增加一道风险,但是相比我们手动加同步块来说,要好的多了
         */
    }
}

2. Singleton1 单例模式-非线程安全

package com.zhaoshuangjian.mode01_单例模式.mode01;

/**
 * Singleton1 单例模式-非线程安全
 *
 * @Auther: zhaoshuangjian  2023-03-23 下午1:09
 */
public class Singleton1 {
    // 私有构造器,防止外部new实例
    private Singleton1(){}

    private static  Singleton1 instance = null;

    /**
     * 非线程安全,多线程下会有问题【多线程抢资源,谁先抢到呢?会不会出现N个线程拿到的实例不是同一个呢?】
     * @return
     */
    public static Singleton1 getInstance() {
        if (instance == null) {
            instance = new Singleton1();
        }
        return instance;
    }

    public void show(){
        System.out.println("你好,我是单例模式一!");
    }
}

3. Singleton2 单例模式-线程安全(对当前单例对象上锁)

package com.zhaoshuangjian.mode01_单例模式.mode01;

/**
 * Singleton2 单例模式-线程安全(对当前单例对象上锁)
 *
 * @Auther: zhaoshuangjian  2023-03-23 下午1:12
 */
public class Singleton2 {
    // 私有构造器,防止外部new实例
    private Singleton2(){}

    private static Singleton2 instance = null;

    /**
     * 虽然线程安全,但是每次调用getInstance获得实例的时候,都会对当前的对象进行加锁
     * 注意,是每一次,这样的话多线程环境下性能会有所下降,但是我们知道单例模式的实例是全局只创建一次的
     * 因此,这个锁不应该在每次获取实例的时候加锁,而应该加在第一次创建对象上
     * @return
     */
    public static synchronized Singleton2 getInstance() {
        if (instance == null) {
            instance = new Singleton2();
        }
        return instance;
    }

    public void show(){
        System.out.println("你好,我是单例模式二!");
    }
}

4.Singleton3 单例模式-线程安全(只在第一次创建实例的时候加锁)

package com.zhaoshuangjian.mode01_单例模式.mode01;

/**
 * Singleton3 单例模式-线程安全(只在第一次创建实例的时候加锁)
 *
 * @Auther: zhaoshuangjian  2023-03-23 下午1:14
 */
public class Singleton3 {
    // 私有构造器,防止外部new实例
    private Singleton3(){}

    private static Singleton3 instance = null;

    /**
     * 区别于Singleton2,注意synchronized关键字【同步块】的位置
     * @return
     */
    public static  Singleton3 getInstance() {
        if (instance == null) {
            synchronized (Singleton3.class){
                if(instance == null){
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }

    public void show(){
        System.out.println("你好,我是单例模式三!");
    }
}

5.Singleton4 单例模式-内部静态工厂类提前创建好实例对象

package com.zhaoshuangjian.mode01_单例模式.mode01;

/**
 * Singleton4 单例模式-内部静态工厂类提前创建好实例对象
 *
 * @Auther: zhaoshuangjian  2023-03-23 下午1:15
 */
public class Singleton4 {
    // 私有构造器,防止外部new实例
    private Singleton4(){}

    private static  class SingletonFactory{
        private static Singleton4 instance = new Singleton4();
    }

    public static  Singleton4 getInstance(){
        return SingletonFactory.instance;
    }

    public void show(){
        System.out.println("你好,我是单例模式四!");
    }
}

你可能感兴趣的:(三,设计模式,单例模式,设计模式,java)