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); 
} 
}

此时的运行结果

小结

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

相关推荐
新缸中之脑1 分钟前
Moltbook 帖子精选
开发语言·php
寄存器漫游者9 分钟前
数据结构 C语言 顺序栈
java·c语言·数据结构
heartbeat..11 分钟前
Redis 性能优化全指南:从基础配置到架构升级
java·redis·性能优化·架构
xyq202412 分钟前
jQuery Mobile 表单选择
开发语言
青岑CTF18 分钟前
攻防世界-Web_php_include-胎教版wp
开发语言·安全·web安全·网络安全·php
m0_7482331718 分钟前
C#与C语言:5大核心语法共性
java·jvm·算法
JavaGuide19 分钟前
推荐一个基于 Spring Boot 4.0 + Java 21 + Spring AI 2.0 的大模型项目!
java·spring boot·spring
雾岛听蓝25 分钟前
C++11 列表初始化与右值引用核心解析
开发语言·c++·经验分享
Maynor99632 分钟前
Clawdbot安装教程:从零开始到接入飞书
java·数据库·飞书
小北方城市网35 分钟前
Spring Boot 多数据源与事务管理实战:主从分离、动态切换与事务一致性
java·开发语言·jvm·数据库·mysql·oracle·mybatis