单例模式

单例模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
1,单例类只能有一个实例。
2,单例类必须自己创建自己的唯一实例。
3,单例类必须给所有其他对象提供这一实例。

代码实现

01-恶汉式-构造器私有

/**
 * @Author huyouting
 * @Date 2021/2/20 14:07
 * @Description:
 */

/**
 * 饿汗式
 * 类加载到内存后,就实例化一个单例,jvm保证线程安全
 * 简单实用,推荐使用
 * 唯一缺点:不管用到与否,类装载时就完成实例化
 */
public class Mgr01 {

    private static final Mgr01 INSTANCE = new Mgr01();

    //构造器私有
    private Mgr01() {
    }

    public static Mgr01 getInstance() {
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        Mgr01 m1 = Mgr01.getInstance();
        Mgr01 m2 = Mgr01.getInstance();
        System.out.println(m1 == m2);
    }
}

02-恶汉式-静态代码块

/**
 * 跟01一个意思
 */
public class Mgr02 {

    private static final Mgr02 INSTANCE;

    static {
        INSTANCE = new Mgr02();
    }

    //构造器私有
    private Mgr02() {
    }

    public static Mgr02 getInstance() {
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        Mgr01 m1 = Mgr01.getInstance();
        Mgr01 m2 = Mgr01.getInstance();
        System.out.println(m1 == m2);
    }
}

03-懒汉式-线程不安全

/**
 * lazy loading
 * 也称懒汉式
 * 虽然达到了按需初始化的目的,但却带来了线程不安全问题
 */
public class Mgr03 {

    private static Mgr03 INSTANCE;

    //构造器私有
    private Mgr03() {
    }

    public static Mgr03 getInstance() {
        if (INSTANCE == null) {
            try {
                Thread.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Mgr03();
        }
        return INSTANCE;
    }

    public void m(){
        System.out.println("m");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                System.out.println(Mgr03.getInstance().hashCode());
            }).start();
        }
    }
}

04-懒汉式-加锁

/**
 * @Author huyouting
 * @Date 2021/2/20 14:16
 * @Description:
 */

/**
 * lazy loading
 * 也称懒汉式
 * 虽然达到了按需初始化的目的,但却带来了线程不安全问题
 * 可以枷锁synchronized,但效率下降
 */
public class Mgr04 {

    private static Mgr04 INSTANCE;

    //构造器私有
    private Mgr04() {
    }

    public static synchronized Mgr04 getInstance() {
        if (INSTANCE == null) {
            try {
                Thread.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Mgr04();
        }
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr04.getInstance().hashCode());
            }).start();
        }
    }
}

05-懒汉式-缩小同步代码块范围

/**
 * @Author huyouting
 * @Date 2021/2/20 14:16
 * @Description:
 */
public class Mgr05 {

    //禁止指令重排,否则会在没有初始化的情况下返回INSTANCE
    private static volatile Mgr05 INSTANCE;

    //构造器私有
    private Mgr05() {
    }

    public static Mgr05 getInstance() {
        if (INSTANCE == null) {
            //试图通过减小同步代码块的方式提高效率,然后不可行
            synchronized (Mgr05.class){
                try {
                    Thread.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                INSTANCE = new Mgr05();
            }
        }
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr05.getInstance().hashCode());
            }).start();
        }
    }
}

06-懒汉式-双重检测锁

/**
 * @Author huyouting
 * @Date 2021/2/20 14:16
 * @Description:
 */
public class Mgr06 {

    private static volatile Mgr06 INSTANCE;

    //构造器私有
    private Mgr06() {
    }

    public static Mgr06 getInstance() {
        if (INSTANCE == null) {
            synchronized (Mgr06.class){
                //双重检测
                if (INSTANCE==null){
                    try {
                        Thread.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    INSTANCE = new Mgr06();
                }
            }
        }
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr06.getInstance().hashCode());
            }).start();
        }
    }
}

07-静态内部类方式

/**
 * @Author huyouting
 * @Date 2021/2/20 14:16
 * @Description:
 */

/**
 * 静态内部类方式
 * JVM保证单例
 * 加载外部类时不会加载内部类,这样可以实现懒加载
 */
public class Mgr07 {

    private Mgr07(){
    }

    private static class Mgr07Holder{
        private final static Mgr07 INSTANCE = new Mgr07();
    }

    public static Mgr07 getInstance(){
        return Mgr07Holder.INSTANCE;
    }

    public void m(){
        System.out.println("m");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr07.getInstance().hashCode());
            }).start();
        }
    }
}

08-枚举

/**
 * 不仅可以解决线程同步,还可以防止反序列化
 */
public enum Mgr08 {

    INSTANCE;

    public void m() {
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr08.INSTANCE.hashCode());
            }).start();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值