JavaEE初阶之单例模式详解

目录

题外话

正题

单例模式

概念

优点

缺点

饿汉式单例模式

代码及详解

懒汉式单例模式

代码及详解

小结


题外话

昨天爬山去了,回来吃了个烧烤有点累,昨天旷了一天,每周稳定发个五篇文章是没什么太大问题的

正题

单例模式

概念

是一种常见的软件设计模式,确保一个类只有唯一一个对象,并提供一个全局访问点去获取这个实例

很多时候我们不需要一个类有多个实例

优点

提供对唯一实例受控访问,减少内存占用,避免资源多重消耗占用

缺点

不提供有惨的构造方法,不易扩展,无法创建多个实例对象,而且可能存在线程安全问题

饿汉式单例模式

所谓饿汉式,就像一个饥饿的人见到健康食物就会迫不及待的吃

在类加载的时候就会创建实例对象,构造函数私有化无法在外面创建对象,保证一个类只有一个单例对象

代码及详解
复制代码
class Singleton{
    //创建私有化静态成员
    private static Singleton instance=new Singleton();
    //提供全局访问方法,去获取唯一的静态成员
    public static Singleton getInstance() {
        return instance;
    }
    //创建私有化构造方法
    private Singleton()
    {

    }
}

这样写无论调用多少次getInstance方法都是唯一的静态成员

示例:

复制代码
public class ThreadDemo16 {
    public static void main(String[] args) {
        Singleton s1=Singleton.getInstance();
        Singleton s2=Singleton.getInstance();
        System.out.println(s1==s2);
    }
}

懒汉式单例模式

懒汉只需要躺在沙发上伸手去拿食物就可以吃

方法调用时会创建唯一的对象

代码及详解
复制代码
class Singletonlazy
{
//创建私有化静态成员instance
private static Singletonlazy instance;
//提供一个公有花静态方法
public static Singletonlazy getInstance()
{
//如果instance为空的时候确保唯一性
    if (instance==null)
    {
//调用构造方法new一个对象
        instance=new Singletonlazy();
    }
//返回instance
    return instance;
}
}

注意:这不是一个线程安全的方法

复制代码
示例:
我们想创建出该类只有唯一一个静态成员,但是如以下代码运行结果可知,这不是线程安全的
public class ThreadDemo17 {
//创建两个静态变量s1,s2
   static Singletonlazy s1;
   static Singletonlazy s2;


    public static void main(String[] args) throws InterruptedException {
//创建t1,t2线程分别调用getInstance方法,赋给s1,s2
        Thread t1=new Thread(()->
        {
            s1=Singletonlazy.getInstance();
        });
        Thread t2=new Thread(()->
        {
            s2=Singletonlazy.getInstance();
        });
//启动t1,t2线程
        t1.start();
        t2.start();
//因为main会很快执行完,有可能t1和t2还没执行完,所以要让t1,t2线程先执行,main最后执行
        t1.join();
        t2.join();
//打印s1,s2地址,判断s1是否和s2是同一个变量
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s1==s2);
    }
}

这就说明我们所创建的懒汉式方法并不是线程安全的

此时我们可以使用锁,代码如下

复制代码
class Singletonlazy {

//创建私有化静态成员
instance private static Singletonlazy instance;

//提供一个公有花静态方法 
public static Singletonlazy getInstance() {

//加锁保证线程安全,注意我加锁的位置!!
synchronized (lock) {

//如果instance为空的时候确保唯一性 
if (instance==null) {

//调用构造方法new一个对象 
instance=new Singletonlazy(); 
}
    }
//返回instance 
return instance; 
} 
}

此时我们再调用这个代码

复制代码
public class ThreadDemo17 {
//创建两个静态变量s1,s2

static Singletonlazy s1; 
static Singletonlazy s2; 
public static void main(String[] args) throws InterruptedException {

//创建t1,t2线程分别调用getInstance方法,赋给s1,s2 
Thread t1=new Thread(()-> 
{ 
s1=Singletonlazy.getInstance(); 
}
); 
Thread t2=new Thread(()-> { 
s2=Singletonlazy.getInstance(); 
}
);

//启动t1,t2线程 
t1.start();
 t2.start();

//因为main会很快执行完,有可能t1和t2还没执行完,所以要让t1,t2线程先执行,main最后执行 
t1.join(); 
t2.join();

//打印s1,s2地址,判断s1是否和s2是同一个变量 
System.out.println(s1); 
System.out.println(s2);
 System.out.println(s1==s2); 
} 
}

此时的运行结果

小结

此篇博客内容到此结束,希望对大家有所帮助,我继续看课程去了!!

相关推荐
Zane1994几秒前
自定义异常该继承 Exception 还是 RuntimeException,就看这一个问题
java·后端
西峰u1 分钟前
Java多线程初阶完整总结|线程、锁、volatile、等待通知、常见案例
java·开发语言·jvm
爱喝可乐的中登10 分钟前
SpringBoot 云边协同|智慧地铁 ISCS 改造实战第 10 篇:全网权限与数据隔离重构|线路‑车站‑专业三级 RBAC、边缘数据权限下沉
java·spring boot·重构
夜雨声烦丿20 分钟前
从需求到页面:日期计算器应用的 ArkTS 原生实现
开发语言·javascript·华为·harmonyos
落魄实习生22 分钟前
Spring AI Alibaba入门-生态集成
java·人工智能·spring
重生之我是Java开发战士30 分钟前
【Java EE】认识Linux与项目部署
java·linux·java-ee
LXMXHJ33 分钟前
springboot项目测试
java·spring boot·后端·测试
程序员雪球41 分钟前
本地IDEA打断点debug容器
java·开发语言
码匠许师傅1 小时前
【设计模式精讲】2. 设计原则基石:SOLID 与几条关键原则
java·设计模式·log4j
yychen_java1 小时前
二:Multi-Agent 协作架构与 MCP 协议实战:Java 企业级 AI 智能体进阶指南
java·人工智能·架构