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

此时的运行结果

小结

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

相关推荐
fl1768316 分钟前
基于python的天气预报系统设计和可视化数据分析源码+报告
开发语言·python·数据分析
Lei活在当下11 分钟前
【现代 Android APP 架构】09. 聊一聊依赖注入在 Android 开发中的应用
java·架构·android jetpack
ACP广源盛1392462567329 分钟前
(ACP广源盛)GSV6172---MIPI/LVDS 信号转换为 Type-C/DisplayPort 1.4/HDMI 2.0 并集成嵌入式 MCU
c语言·开发语言·单片机·嵌入式硬件·音视频
不穿格子的程序员40 分钟前
从零开始刷算法-栈-括号匹配
java·开发语言·
雪域迷影1 小时前
C#中通过get请求获取api.open-meteo.com网站的天气数据
开发语言·http·c#·get
lkbhua莱克瓦241 小时前
Java练习-正则表达式 1
java·笔记·正则表达式·github
yue0081 小时前
C#类继承
java·开发语言·c#
Want5951 小时前
Python汤姆猫
开发语言·python
Larry_Yanan1 小时前
QML学习笔记(五十)QML与C++交互:QML中单例C++对象
开发语言·c++·笔记·qt·学习·ui·交互
凯芸呢1 小时前
Java中的数组(续)
java·开发语言·数据结构·算法·青少年编程·排序算法·idea