多线程06 单例模式,阻塞队列以及模拟实现

简介: 多线程06 单例模式,阻塞队列以及模拟实现

前言

上篇文章我们讲了wait和notify两个方法的使用.至此,多线程的一些基本操作就已经结束了,今天我们来谈谈多线程的一些简单应用场景.

单例模式

单例模式,顾名思义,只有一个实例的模式,我们有两种实现方式,分别是懒汉式和饿汉式,我们来分别给出代码.

饿汉式(此处的饿表示创建实例的迫切,所以我们定义成一个类变量即可,然后提供他的私有构造方法,提供获取实例的方法,由于是随着类的加载而加载,所以该实例是无线程安全问题的.)

class singleTon{
    private static singleTon instance = new singleTon();
    public static singleTon getInstance(){
        return instance;
    }
    private  singleTon(){
    }
}

懒汉式(需要的时候再创建,这个是在第一次使用的时候再创建实例,就有可能引发线程安全的问题,下面我给出代码)

class SingleTonLazy{
    //引用指向唯一实例
    private static volatile SingleTonLazy instance = null;
    private static final Object lock = new Object();
    public static SingleTonLazy getInstance(){
        if(instance == null){
            synchronized (lock){
                if(instance == null){
                    instance = new SingleTonLazy();
                }
            }
        }
        return instance;
    }
    private SingleTonLazy(){
    }
}

你可能会想,这里为啥判断了两次instance不为空,并且又加了一个锁呢??

1.首先,内层if是判断是否要创建instance对象

2.加锁的原因是在多线程的情况下,可能cpu调度到线程1后执行了一个判断,就去调度到线程2了,然后再次调度到线程1时,又创建了一个实例,此时这个锁是为了帮助判空创建对象的操作保证原子性的

3.最后一个if其实是为了不让每次都持有和释放锁,只有第一次持有和释放锁,来降低锁的消耗

阻塞队列

下面我们介绍一下阻塞队列,基于这个就构成了当前经常使用的 - 消息队列

其实在日常生活中,它的使用很多,比如举例如下

淘宝等商城软件,在首页要获取到用户信息和商品信息

这样假设用户信息服务器挂了,可能导致整个服务挂了

此时我们引入消息队列

让请求接收服务器直接将请求放到信息队列中,让其他的服务器依次来取即可

好处

1.降低了服务器之间的耦合度,此时如果添加服务器可以直接添加,一个服务器宕机对其他的服务影响小

2.削峰填谷

请求多的时候,可以先存放在消息队列中慢慢处理

下面我们来简单实现一个简易消息队列(基于循环队列)

class MyBlockingQueue{
    private String[] elems = null;
    private int head = 0;
    private int tail = 0;
    private int size = 0;
    private  final  Object lock = new Object();
    public MyBlockingQueue(int capacity) {
        elems = new String[capacity];
    }
    public void put(String elem) throws InterruptedException {
        synchronized (lock){
            while (size >= elems.length){
                //满了需要阻塞
                lock.wait();
            }
            //加元素
            elems[tail] = elem;
            tail++;
            if(tail>=elems.length){
                tail = 0;
            }
            //使用elem % elems.length也行
            size++;
            lock.notify();
        }
    }
    public String take() throws InterruptedException {
        synchronized (lock){
            while(size == 0){
                lock.wait();
                //阻塞
            }
            String elem = elems[head];
            head++;
            if(head>= elems.length){
                head = 0;
            }
            size--;
            lock.notify();
            return elem;
        }
    }
}
相关文章
|
2月前
|
存储 监控 安全
一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)
这篇文章是Java面试第三天的笔记,讨论了线程安全、Thread与Runnable的区别、守护线程、ThreadLocal原理及内存泄漏问题、并发并行串行的概念、并发三大特性、线程池的使用原因和解释、线程池处理流程,以及线程池中阻塞队列的作用和设计考虑。
|
15天前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
1月前
|
安全 Java 关系型数据库
单例模式下引发的线程安全问题
单例模式确保类在进程中仅有一个实例,适用于如数据库连接等场景。分为饿汉式与懒汉式:饿汉式在类加载时创建实例,简单但可能浪费资源;懒汉式延迟创建实例,需注意线程安全问题,常采用双重检查锁定(Double-Checked Locking)模式,并使用 `volatile` 关键字避免指令重排序导致的问题。
46 2
单例模式下引发的线程安全问题
|
3天前
|
消息中间件 NoSQL 关系型数据库
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
16 0
|
3天前
|
设计模式 安全 Java
【多线程-从零开始-柒】单例模式,饿汉和懒汉模式
【多线程-从零开始-柒】单例模式,饿汉和懒汉模式
19 0
|
3月前
|
设计模式 安全 Java
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
66 1
|
2月前
|
设计模式 SQL 安全
单例模式大全:细说七种线程安全的Java单例实现,及数种打破单例的手段!
设计模式,这是编程中的灵魂,用好不同的设计模式,能使你的代码更优雅/健壮、维护性更强、灵活性更高,而众多设计模式中最出名、最广为人知的就是Singleton Pattern单例模式。通过单例模式,我们就可以避免由于多个实例的创建和销毁带来的额外开销,本文就来一起聊聊单例模式。
|
3月前
|
微服务
多线程内存模型问题之在单例模式中,volatile关键字的作用是什么
多线程内存模型问题之在单例模式中,volatile关键字的作用是什么
|
3月前
|
设计模式 安全 Java
Java面试题:解释单例模式的实现方式及其优缺点,讨论线程安全性的实现。
Java面试题:解释单例模式的实现方式及其优缺点,讨论线程安全性的实现。
26 0
|
3月前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
48 0

热门文章

最新文章