单例模式全解

前言

本文会把我所掌握的所有单例模式都写下
说实话 写法一大堆 网上一查一大把 我总结一下 同时写一下自己的理解和各种单例模式的关系,也算是一个笔记

分类

单例模式写法千千万 总共分为四大类:

  1. 懒汉式
  2. 饿汉式
  3. 注册式
  4. ThreadLocal

恶汉式

public class HungrySingleton {
    private static HungrySingleton instance = new HungrySingleton();
    private HungrySingleton (){
    throws new RunTime
    }
    public static HungrySingleton getInstance(){
        return instance;
    }
}
特点:
·线程安全,但容易造成资源浪费,如果不instance不被使用,这个对象就占用无意义的内存

简单懒汉式

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
特点
·不浪费内存  但是线程不安全    举例说明   如果T1 线程判断实例为空  开始创建对象并赋值
在创建对象过程中 T2进入 也发现实例为空  所以又会创建对象  这样打破了单例规则

懒汉式 同步锁方式

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {
    }

    public synchronized static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
特点
·不浪费内存  线程安全   但当实例已经创建完成的时候依然会上锁 非常影响性能

懒汉式 双重检查锁方式

public class DoubleCheck {
    private static DoubleCheck instance;

    private DoubleCheck() {
    }

    public static DoubleCheck getInstance() {
        if (instance == null) {
            synchronized (DoubleCheck.class) {
                if (instance == null) {
                    instance = new DoubleCheck(); //标记
                }

            }
        }
        return instance;
    }
}
特点
懒汉式上锁的变种    
·绝大部分解决了效率问题   可惜也有线程安全性问题
下面详解   

在《并发编程的艺术》一书中提到过 在代码标记处 可能出现内存指令重排
标记处一共经历了三件事

  1. 分配内存地址 memory
  2. 创建对象 初始化对象
  3. 赋值 memory = 对象

这个过程是完全符合指令重排的要求的 如果发生了指令重排 会变成
在这里插入图片描述


线程安全的懒汉式

public class Safe {
    private volatile static Safe instance;

    private Safe() {
    }

    public static Safe getInstance() {
        if (instance == null) {
            synchronized (Safe.class) {
                if (instance == null) {
                    instance = new Safe();
                }
            }
        }
        return instance;
    }
}
增加volatile关键字禁止指令重排 

静态内部类

public class StaticInner {
    private StaticInner(){

    }
    public static StaticInner getInstance(){
        return A.instance;
    }
    private static class A{
        private static StaticInner instance = new StaticInner();
    }

}

看似像饿汉  其实是懒汉
利用的是JVM机制   JVM对于内部类是延迟加载的 当内部类被使用到的时候才会加载
自动帮我们做了懒汉式的处理
但是能被反射破坏 

反射破坏单例

我们可以通过反射获取私有的构造方法 手动调用
我们可以在构造方法中抛出异常

private AAA(){
if( null != instance){
	throw new RuntimeException();
}
}

枚举单例

public enum EnumSingleton {
    // 单例
    INSTANCE;

    private Object object;


    public EnumSingleton getInstance(){
        return INSTANCE;
    }

    public Object getObject() {
        return object;
    }

    public EnumSingleton setObject(Object object) {
        this.object = object;
        return this;
    }

}
直接调用getInstance方法 得到的实例一定是单例的 然后通过setObject 进行属性赋值

枚举在JDK层面就已经定义了不能使用构造方法创建
在这里插入图片描述


注册式单例

最后一种也是最简单的一种单例模式
其实就是缓存容器
spring的ApplicationContext就是一个大容器 我们通过getBean获取实例 其一定是单例的
spring的bean默认也是单例的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值