千家信息网

java单例模式怎么定义

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"java单例模式怎么定义"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、单例模式定
千家信息网最后更新 2026年11月02日java单例模式怎么定义

本篇内容介绍了"java单例模式怎么定义"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、单例模式定义:
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

1、经典饿汉式:

public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return INSTANCE;
}
}
特点:程序启动时加载,先加载类,再初始化静态属性,由于后面无法再对对象进行修改,从而实现线程安全,效率相对高一些。占用内存相对多一些。

缺点:如果这个类特别庞大,初始化时将会特别缓慢,还有就是如果我们用不到这个类,它仍然会创建出来,浪费了资源。

2、经典懒汉式:

public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
特点:延时加载,节约了内存。效率相对低一些。利用同步块实现线程安全。

缺点:synchronized关键字是一个重锁(对象锁),它会每次调用getInstance(),都要对对象上锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了。

3、懒汉式变种-双重检查结构(不加volatile关键字修饰):

package cn.hzy.creationPattern.singleton;

public class Singleton3 {
private static Singleton3 instance = null;
private Singleton3(){
}
public static Singleton3 getInstance(){
if (instance == null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
特点:属于懒汉式的变种,上面懒汉式的特点都有,但是这里优化了性能问题,没有给getInstance()方法加锁,而是只给instance = new Singleton3();加锁,也就是说只在初始化的时候会加锁,后面的访问因为instance!=null,就不会加锁。

缺点:乍一看这种模式既没有线程安全问题,又保证了单例,貌似完美了,但是JVM在创建对象的时候有可能为了优化性能而进行指令重排,

看似简单的一句 instance = new Singleton3(); JVM在创建对象的时候会有三个步骤:

1、给Singleton3分配一个内存空间

2、初始化Singleton3(也就是创建Singleton3对象)

3、将instance指向刚分配的内存空间地址

但是有可能JVM为了编译的优化提高效率就有可能变成下面一种顺序:

1、给Singleton3分配一个内存空间

2、将instance指向刚分配的内存空间地址

3、初始化Singleton3(也就是创建Singleton3对象)

其实这种情况在单线程情况下是毫无影响的,结果都一样,但是如果在多线程情况下,就有可能导致错误。

比如:A、B两个线程访问getInstance()方法,A先进入第一个if判断,然后进入synchronized块,开始初始化Singleton3,由于发生了指令重排,将instance指向刚分配的内存空间地址(此时未创建Singleton3对象),在这个时候,B访问getInstance()方法,B进入第一个if判断,因为instance已经指向了一个存在的内存空间地址,即instance!=null,此时直接返回instance(未初始化),然后再调用的时候如果A还没有初始化完毕那么就会报空指针错误。(概率很低)

解决方案:加上volatile关键字修饰,

volatile:

特性一:内存可见性,即线程A对volatile变量的修改,其他线程获取的volatile变量都是最新的。

特性二:可以禁止指令重排序。

修改如下:将 private static Singleton3 instance = null; 改为 private static volatile Singleton3 instance = null;

4、静态内部类:

package cn.hzy.creationPattern.singleton;

public class Singleton4 {
private Singleton4() {}

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

private static class SingletonFactory {
private static Singleton4 instance = new Singleton4();
}
}
特点:按特征也是属于懒汉模式,因为只会在我们需要用的时候才会创建实例对象,这里通过构造函数私有化,使用内部类来维护单例的实现,因为JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次, 并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心Singleton3出现的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。

缺点:貌似这个就完美了,但是静态内部类也有着一个致命的缺点,就是传参的问题,由于是静态内部类的形式去创建单例的,故外部无法传递参数进去的。

5、枚举:

public enum Singleton {
INSTANCE;
public void method() {
}
}
直接调用SingleTon.INSTANCE就是单例。

特点:创建枚举默认就是线程安全的

优点:简直不要太多,1、写法简单,对比上面的实例就能发现。2、可以防止反射攻击。

针对上面的反射攻击我这里简单说一下:在上面的1、2、3、4种单例模式里面,如果不对构造函数做一些安全处理,我们可以很轻松通过反射拿到构造器并且创建不只一个实例对象,就不再是单例了。但是对于枚举,即时你通过反射拿到构造器,在创建对象实例的时候也会报错,因为枚举是可以防止反射攻击的。

怎么对构造函数做一些安全处理?

可以立一个flag,在创建一个对象实例后,改变flag的值,通过判断抛出异常。

比如:

private static boolean flag = false;
private Singleton (){
synchronized (Singleton .class) {
if(false == flag){
flag = !flag;
} else {
throw new RuntimeException("单例模式正在被反射攻击!!!");
}
}
}
通过在构造函数里面增加一个判断来保证不被反射攻击。

"java单例模式怎么定义"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

对象 时候 线程 内存 模式 实例 反射 安全 特点 空间 就是 懒汉 缺点 问题 保证 分配 攻击 函数 同时 地址 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技有限公司 苏州找大状互联网科技有限公司 国智互联网科技 科技金融是不是互联网金融 深圳科技互联网 互联网科技金融公司 互联网科技媒体 互联网科技生活的内容 科技大学互联网专业好不好 上海电发互联网科技有限公司 成都互联网科技公司工作好不好 济南有互联网科技公司吗 工业互联网展湾科技股份有限公司 互联网企业科技类企业如何做账 中天科技中国工业互联网 互联网科技年终奖 图游互联网科技 上海同邻互联网科技有限公司规模 西安左小互联网科技有限公司 杭州科技互联网公司有哪些 腾讯阿里互联网科技 科技互联网公司logo 成都仁贤领冠互联网科技有限公司 互联网教育科技公司vipkid 燊美集互联网科技有限公司 互联网科技创新的路径 世界互联网领先科技成果获奖 全球科技与互联网公司市值变化 亚光科技低轨卫星互联网 华人运通互联网科技公司
0