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

此时的运行结果

小结

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

相关推荐
q***33371 小时前
oracle 12c查看执行过的sql及当前正在执行的sql
java·sql·oracle
tobebetter95274 小时前
How to manage python versions on windows
开发语言·windows·python
Y***h1874 小时前
第二章 Spring中的Bean
java·后端·spring
9***P3344 小时前
PHP代码覆盖率
开发语言·php·代码覆盖率
8***29314 小时前
解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域
java·前端·spring
CoderYanger5 小时前
优选算法-栈:67.基本计算器Ⅱ
java·开发语言·算法·leetcode·职场和发展·1024程序员节
jllllyuz5 小时前
Matlab实现基于Matrix Pencil算法实现声源信号角度和时间估计
开发语言·算法·matlab
q***06295 小时前
Tomcat的升级
java·tomcat
多多*5 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
青云交5 小时前
Java 大视界 -- Java 大数据在智能物流无人配送车路径规划与协同调度中的应用
java·spark·路径规划·大数据分析·智能物流·无人配送车·协同调度