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等⽅法,但是这些⽅法不带有阻塞特性

相关推荐
独立开发之道13 分钟前
【Three.js教程】 图元速查:官方内置的立体图形
开发语言·javascript·ecmascript
Htr_15 分钟前
Python面向对象编程:类与对象基础
开发语言·python
RD_daoyi16 分钟前
谷歌改写了76%的标题:超60字符的,95%会被谷歌自己重写
大数据·服务器·开发语言·前端·搜索引擎·html
weixin_3077791317 分钟前
AI生成代码的隐患与治理:人工审查流程及提示词驱动的修复策略
开发语言·人工智能·算法
Java后端的Ai之路21 分钟前
09、Python组合模式
开发语言·人工智能·python·docker·组合模式
Escalating_xu26 分钟前
【C++入门基础(上)】从发展历程、学习路线到命名空间与输入输出
开发语言·c++
jimy129 分钟前
C++ 中的rValue的判断---是否能“隐式移动”
开发语言·c++
xxy2224132 分钟前
TCP 网络编程(3):从基础通信到并发服务器与 HTTP 实战
开发语言·php
zcmodeltech33 分钟前
垃圾发电厂沙盘模型控制系统设计与实现:多设备协同联动方案
java·大数据·数据库·人工智能·stm32·嵌入式硬件·制造