JavaEE初阶 多线程:单例模式 | 阻塞队列

Singleton 单例模式

单例模式能保证某个类在程序中只存在唯⼀⼀份实例,⽽不会创建出多个实例。

单例模式最常⻅的实现⽅的是"饿汉"和"懒汉"两种

饿汉模式,运行即创建

java 复制代码
class Singleton{
    private static Singleton instance=new Singleton();
    private static Singleton getinstance(){
        return instance;
    }
    //构造方法私有化,仅限在Singleton类中实例化,确保单例化
    private  Singleton(){
    }
}

懒汉模式,需要时再创建

java 复制代码
class Singleton{
    private static Object locker=new Object();
//volatile修饰instance
    private static volatile Singleton instance=null;
    public static Singleton getinstance(){
if (instance==null){
    synchronized (locker){
        if (instance==null){
            instance=new Singleton();
        }
    }
}
        //实例化时原子操作
        return instance;
    }
    //构造方法私有化,仅限在Singleton类中实例化,确保单例化
    private  Singleton(){
    }
}

饿汉模式不存在线程安全问题,懒汉模式当多个线程调用getInstance⽅法,就可能导致创建 出多个实例,后面的实例会覆盖前面实例,资源浪费。

⼀旦实例已经创建好了,后⾯再多线程环境调⽤getInstance就不再有线程安全问题了(不再修改 instance 了)

使用锁保证原子性

java 复制代码
//判断是否需要加锁,已经创建实例后减少资源浪费
if (instance==null){
    synchronized (locker){
//判断是否需要实例化
        if (instance==null){
            instance=new Singleton();
        }
    }
}

但线程在加锁操作时仍会被调度,导致t1线程中instance使用了未初始化的实例,因此需要加入volatile避免重排序

java 复制代码
class DBUtil {
    private static volatile DataSource dataSource = null;

    public static DataSource getInstance() {
        if (dataSource == null) {
            synchronized (DBUtil.class) {
                if (dataSource == null) {
                    MysqlDataSource ds = new MysqlDataSource();
                    ds.setUrl("jdbc:mysql://127.0.0.1:3306/java117?characterEncoding=utf8&useSSL=false");
                    ds.setUser("root");
                    ds.setPassword("2222");
                    dataSource = ds;
                }
            }
        }
        return dataSource;
    }
   private DBUtil{}
}

阻塞队列

阻塞队列是⼀种特殊的队列.也遵守"先进先出"的原则,具有线程安全的阻塞队列

1.当队列满的时候,继续⼊队列就会阻塞,直到有其他线程从队列中取⾛元素.

2.当队列空的时候,继续出队列也会阻塞,直到有其他线程往队列中插⼊元素.

阻塞的队列的应用场景:生产消费者模型

阻塞队列的使用

在Java标准库中内置了阻塞队列.如果我们需要在⼀些程序中使⽤阻塞队列,直接使⽤标准库中的即 可.

1.BlockingQueue是⼀个接⼝.真正实现类包括LinkedBlockingQueue/ArrayBlockingQueue/PriorityBlockingQueue.

2.put⽅法 ⽤于阻塞式的⼊队列,take⽤于阻塞式的出队列.

3.BlockingQueue也有offer,poll,peek等⽅法,但是这些⽅法不带有阻塞特性

相关推荐
懂点Tech7 小时前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
云和数据.ChenGuang7 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠7 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
美狐美颜SDK开放平台8 小时前
视频美颜SDK试用DEMO阶段应该测试什么?直播APP接入实操指南
开发语言·人工智能·深度学习·音视频·美颜sdk·直播美颜sdk·第三方美颜sdk
dtq04248 小时前
C++小案例 - 日志实战
开发语言·c++
星夜离尘569 小时前
MATLAB ADC 码流触顶诊断:命中数、缺口分段与削顶不可辨识性
开发语言·matlab
码匠许师傅9 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
码匠许师傅10 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
silvamux_10 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
bkspiderx11 小时前
基于Socket的广播通信及C语言实现详解
c语言·开发语言·socket·广播·socket的广播通信