当前位置: 首页 > news >正文

认识多线程:单例模式

多线程是并发编程的核心概念,也是面试中的高频考点。本文将围绕多线程中的单例模式、阻塞队列及生产者消费者模型展开,结合代码实例帮助大家理解这些基础知识点。

一、单例模式:懒汉与饿汉

单例模式是最常用的设计模式之一,其核心是保证一个类在全局只有唯一实例,并提供一个访问该实例的全局入口。在多线程场景下,实现安全的单例模式需要特别注意线程同步问题。

1. 饿汉模式

饿汉模式的特点是"饿",即类加载时就创建实例,天然线程安全。

// 饿汉模式
public class SingletonHungry {// 类加载时就初始化实例private static final SingletonHungry instance = new SingletonHungry();// 私有构造方法,防止外部实例化private SingletonHungry() {}// 提供全局访问点public static SingletonHungry getInstance() {return instance;}
}

优点:实现简单,线程安全(类加载过程由JVM保证线程安全)
缺点:如果实例创建成本高且长时间不使用,会造成资源浪费

2. 懒汉模式(线程安全版)

懒汉模式的特点是"懒",即用到时才创建实例。但需要通过同步锁和双重检确保线程安全。

// 懒汉模式(线程安全版)
public class SingletonLazy {// volatile修饰:防止指令重排序导致的空指针问题private static volatile SingletonLazy instance=null;private static Object locker=new Object();// 私有构造方法private SingletonLazy() {}// 双重检查锁定(Double-Checked Locking)public static SingletonLazy getInstance() {// 第一次检查:避免不必要的锁竞争if (instance == null) {// 加锁:保证同步创建实例synchronized (locker) {// 第二次检查:防止多线程同时通过第一次检查后重复创建if (instance == null) {instance = new SingletonLazy();}}}return instance;}
}

关键技术点解析

  • 双重if检查:外层if避免每次调用都加锁(提高效率),内层if防止多线程同时进入临界区后重复创建实例
  • volatile修饰instance = new SingletonLazy()实际分为3步(分配内存→初始化对象→赋值引用),volatile可禁止指令重排序,避免其他线程获取到未初始化的实例

二、阻塞队列:并发场景的"缓冲区"

阻塞队列(BlockingQueue)是多线程编程中的重要工具,它提供了一种线程安全的队列操作方式,核心特性是:

  1. 阻塞特性:当队列满时,入队操作阻塞;当队列空时,出队操作阻塞
  2. 削峰填谷:平衡生产者和消费者的处理能力(比如秒杀场景中缓冲突发请求)
  3. 解耦作用:生产者和消费者无需知道对方存在,通过队列间接交互

基于阻塞队列的生产者消费者模型

生产者消费者模型是并发编程中的经典模式,通过阻塞队列实现可大幅简化代码:

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;public class Demo27 {public static void main(String[] args) {BlockingDeque<Integer> deque=new LinkedBlockingDeque<>();Thread producer=new Thread(()->{int n=0;while (true){try {Thread.sleep(500);deque.put(n);System.out.println("生产"+n);n++;} catch (InterruptedException e) {throw new RuntimeException(e);}}},"producer");Thread consumer=new Thread(()->{while (true){try {Thread.sleep(1000);Integer n = deque.take();System.out.println("消费" + n);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"consumer");producer.start();consumer.start();}
}

运行效果
生产者每0.5秒生产一个数据,消费者每1秒消费一个数据.

三、手动实现阻塞队列

理解阻塞队列的内部原理,有助于更好地使用它。我们可以基于数组和ReentrantLock实现一个简单的阻塞队列:


class MyBlockingQueue {private String[] data = null;private int head = 0;private int tail = 0;private int size = 0;public MyBlockingQueue(int capacity) {data = new String[capacity];}public void put(String elem) throws InterruptedException {synchronized (this) {while (size >= data.length) {this.wait();}data[tail++] = elem;if (tail >= data.length) {tail = 0;}//tail=(tail+1)%data.length;}size++;this.notify();}}public String take() throws InterruptedException {synchronized (this) {while (size == 0) {this.wait();}String ret = data[head];head++;if (head >= data.length) {head = 0;}size--;this.notify();return ret;}}
}public class Demo28 {public static void main(String[] args) {MyBlockingQueue queue=new MyBlockingQueue(50);Thread producer=new Thread(()->{int n=0;while (true){try {queue.put(n+"");System.out.println("生产元素"+n);n++;Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});Thread consumer=new Thread(()->{String n=null;while (true){try {Thread.sleep(1000);n=queue.take();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("消费元素"+n);}});producer.start();consumer.start();}
}

核心实现思路

  1. 用数组实现循环队列(通过取模运算处理指针越界)
  2. 用ReentrantLock保证线程安全,避免并发问题
  3. 用两个Condition对象分别处理"队列满"和"队列空"的阻塞等待

总结

本文介绍了多线程中的三个核心知识点:

  1. 单例模式的两种实现(饿汉模式简单安全,懒汉模式需双重检查+volatile保证线程安全)
  2. 阻塞队列的特性及生产者消费者模型(解耦+削峰填谷的关键工具)
  3. 阻塞队列的手动实现(基于锁和条件变量的经典并发编程实践)

掌握这些基础知识,是深入学习多线程编程的基础。实际开发中,JDK提供了丰富的并发工具类(如ArrayBlockingQueueConcurrentHashMap等),理解其底层原理能帮助我们更好地运用它们解决实际问题。

http://www.dtcms.com/a/561013.html

相关文章:

  • 深入解析 HarmonyOS 中 NavDestination 导航目标页的生命周期
  • 3、webgl 基本概念 + 绘制线段 + 绘制三角形
  • 【LeetCode热题100(58/100)】单词搜索
  • 旅行社网站模版网页设计六安模板
  • 求解器驱动智能决策新纪元
  • 简单网站制作成品广东省广州市佛山市
  • 使用 TransGPTex 将 LaTeX 英文论文翻译成中文:完整实战教程
  • APIJSON:用JSON自动生成API,告别手写CRUD!【.NET 8 集成案例,也支持JAVA】
  • 网络版本计算器
  • 视频容器(如 MP4)的作用:组织与同步
  • 餐饮加盟网网站建设网站建设案例新闻
  • 梅州站改造高铁站优化方案英语必修三电子版
  • vue 项目中常用的 2 个 Ajax 库
  • 【NX 8.5】【vs2022】二开环境配置
  • HexStrike使用搭建
  • 历史数据分析——云南铜业
  • 金昌市住房和城乡建设局网站兴平网站开发
  • 使用Docker构建Node.js应用的详细指南
  • 微信小程序动态二维码外部实时展示系统
  • 建设银行贵阳银行下载官方网站做网站排名优化有用吗
  • 【软件安全】Linux GDB在软件安全中的概念和应用
  • DashGo零基础入门 纯Python的管理系统搭建
  • 1. 工厂方法模式
  • 【2025 SWPU-NSSCTF 秋季训练赛】jicao
  • 网站建设.龙兵科技做推广的网站那个好
  • trimesh库初步接触
  • 对链表进行插入排序:用Java实现
  • 资讯类网站建设方案书docker wordpress 4.2
  • 设计模式——原型模式(prototype)
  • 设计模式-单列模式