单例模式-懒汉式&饿汉式

单例的四个原则

⚫ 构造私有
⚫ 以静态方法或者枚举返回实例
⚫ 确保实例只有一个,尤其是多线程环境
⚫ 确保反序列换时不会重新构建对象

一,懒汉式

当调用创建实例方法的时候创建唯一的实例

1.1 第一种编码-存在线程安全问题

public class LazySingleton01 {
    // 构造器私有化
    private LazySingleton01(){}
    private static LazySingleton01 lazySingleton01=null;
    public static LazySingleton01 getInstance(){
        if(lazySingleton01==null){
            lazySingleton01= new LazySingleton01();
        }
        return lazySingleton01;
}

1.1.1 单线程运行测试-没问题

    public static void main(String[] args) {
        for (int i = 0; i <10 ; i++) {
            LazySingleton01 instance = LazySingleton01.getInstance();
            System.out.println(instance);
        }
    }

在这里插入图片描述
1.1.2 多线程运行测试

// 创建线程
public class SingletonMuchThread implements Runnable{
    Set<LazySingleton01> singletons=new HashSet<LazySingleton01>();
    public void run() {
        LazySingleton01 instance = LazySingleton01.getInstance();
        singletons.add(instance);
    }
}
// 启动线程
public class TestSingleton {
    public static void main(String[] args) throws InterruptedException {
        SingletonMuchThread singletonMuchThread=new SingletonMuchThread();
        new Thread(singletonMuchThread).start();
        new Thread(singletonMuchThread).start();
        new Thread(singletonMuchThread).start();
        new Thread(singletonMuchThread).start();
        new Thread(singletonMuchThread).start();
        new Thread(singletonMuchThread).start();
        new Thread(singletonMuchThread).start();
        Thread.sleep(2000);
        System.out.println(singletonMuchThread.singletons);
    }
}

1.1.3 结果-未达到单例的效果
在这里插入图片描述
1.2 懒汉式线程安全性改进-方式1-加同步锁

public class LazySingleton01 {
    // 构造器私有化
    private LazySingleton01(){}
    private static LazySingleton01 lazySingleton01=null;
    public static LazySingleton01 getInstance(){
        synchronized (LazySingleton01.class){
            if(lazySingleton01==null){
                lazySingleton01= new LazySingleton01();
            }
        }
        return lazySingleton01;
    }
}

1.3 懒汉式线程安全性改进-方法二 - 双重检查锁

public class LazySingleton01 {
    // 构造器私有化
    private LazySingleton01(){}
    private volatile  static LazySingleton01 lazySingleton01=null;
    public static LazySingleton01 getInstance(){
            if(lazySingleton01==null){
                synchronized (LazySingleton01.class){
                    if(lazySingleton01==null){
                        lazySingleton01= new LazySingleton01();
                    }
                }
        }
        return lazySingleton01;
    }
}

1.4 静态内部类方式(快速安全)

 虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确地加锁、同步,
 如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的<clinit>()方法,
 其他线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕。
 如果在一个类的<clinit>()方法中有耗时很长的操作,
 就可能造成多个进程阻塞(需要注意的是,其他线程虽然会被阻塞,
 但如果执行<clinit>()方法后,其他线程唤醒之后不会再次进入<clinit>()方法。
 同一个加载器下,一个类型只会初始化一次。),在实际应用中,这种阻塞往往是很隐蔽的。
————————————————
版权声明:本文为CSDN博主「走着不语」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mnb65482/article/details/80458571
public class LazySingleton02 {
    private LazySingleton02(){}
    private static class InnerObject{
       private static LazySingleton02 singleton02=new LazySingleton02();
    }
    public static LazySingleton02 getinstance(){
        return InnerObject.singleton02;
    }
}

二,饿汉式

把实例在内存中创建好,随时获取唯一一个实例,线程绝对安全
public class HurrySingleton {
    private HurrySingleton(){};
    private static HurrySingleton singleton=new HurrySingleton();
    public static HurrySingleton getInstance(){
        return singleton;
    }
}

单例模式几种实现经典解释
https://blog.csdn.net/mnb65482/article/details/80458571?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162271784916780265462860%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162271784916780265462860&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-80458571.first_rank_v2_pc_rank_v29&utm_term=%E9%9D%99%E6%80%81%E5%86%85%E9%83%A8%E7%B1%BB%E5%AE%9E%E7%8E%B0%E5%8D%95%E4%BE%8B&spm=1018.2226.3001.4187

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值