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

[Java基础-线程篇]7_线程设计模式与总结

摘要:懒汉单例模式怎么变得线程安全?Master-Worker归并模式,工作窃取算法。Java线程相关源码使用了什么设计模式?

资料引用:《Java高并发核心编程·卷2》

目录

线程安全的单例模式

Master-Worker模式

工作窃取算法

并发总结

线程篇归纳

Thread

JUC

异步

代码质量

模式总结


线程安全的单例模式

懒汉模式,即调用才创建的单例模式在高并发情况下,会有多个单例的情况。
解决方案-双重校验+volatile:
检查是否已经创建——>加锁创建过程——>创建前判断是否已经创建
第二次检查主要是防止其他线程已经通过第一次检查等待获取锁。
volatile关键字禁止实例创建过程中的指令重排。
/**
 * 双重检查锁,解决多线程可能出现的多实例问题
 */
public class SingleTon2 {

    private static volatile SingleTon2 singleton;

    private SingleTon2() {
    }

    public static SingleTon2 getInstance() {
        if (singleton == null) {
            synchronized (SingleTon2.class) {
                if (singleton == null) {
                    singleton = new SingleTon2();
                }
            }
        }
        return singleton;
    }

    //类中其他方法,尽量是static
    public static void doSomething() {
        System.out.println("doSomething");
    }
}

Master-Worker模式

一种归并类型的模式。
任务的调度和执行分离,调度角色为Master,执行任务的角色为Worker,Master负责接收、分配任务和合并(Merge)结果,Woker执行任务。
Master-Worker 这种模式适合小规模任务分发。
大规模调度需另外设计如:事件驱动+MapReduce,去中心化、实时性、规模化处理更接近现代分布式架构。其设计目标是高效处理海量并发请求,保证准确性和一致性,而非简单依赖单一Master协调。

工作窃取算法

工作窃取算法的核心思想是:工作线程自己的活干完了之后,会去看看别人有没有没干完的活,如果有就拿过来帮忙干。工作窃取算法的主要逻辑:每个线程拥有一个双端队列(本地队列),用于存放需要执行的任务,当自己的队列没有任务时,可以从其他线程的任务队列中获得一个任务继续执行。

并发总结

对于并发、分布式来说,线程\节点之间的同步是有明显开销的,应该用尽可能少的同步做到相同的效果。
原则:
  • 无锁优先:用CAS(如AtomicInteger)或无共享数据替代锁。
  • 局部化:线程/节点尽量独立计算,减少交互。
  • 异步化:用事件驱动或消息队列(如Kafka)解耦同步依赖。
  • 最终一致性:分布式场景下,牺牲强一致性换取性能(如BASE模型)。

线程篇归纳

Thread

Java从线程的设计开始,除了设计有线程通用结构——线程ID、名称、状态、优先级,也为线程安全与线程状态流转做了设计。
且使用数字+枚举类转换的方式,减少了线程实例对象本身的运行开销。
对于线程状态的操纵,提供了不同的方法进行,对于阻塞状态,加重入锁。
对于线城池,Java将工作线程封装成Worker对象,并使用HashSet来存储工作线程,BlockingQueue来作为工作任务队列,且很好地使用了队列的阻塞方法来实现核心线程的不被清除。

JUC

JUC为了保证线程的原子性、可见性、有序性,大量使用CAS操作与volatile关键字。
能使用CAS的场景都使用了CAS,无锁优先,又针对CAS的问题,先后迭代有“热点分离”、“队列削峰”的设计来减少CAS自旋带来的性能损失。
对于CAS+volatile+版本号保证原子性、可见性、解决ABA问题,Java也设计有对应原子类如AtomicStampedReference等,使用的版本号为别的int类型与boolean类型。

异步

JUC异步模式有Master-Worker的归并模式,ForkJoin的异步使用“工作窃取算法”来提速分治后的任务处理速度。

代码质量

在线程相关的Java代码中,可以看到Java源码设计的非常严谨优雅,以线程池为例,基本设置为volatile保证可见性,对于没有设置volatile的属性,其仅在锁范围内使用。
又以CAS自旋为例,基本使用for(;;)的形式进行自旋。
体现了Java本身继承、封装、多态特性。以线程创建方式为例,体现有适配器与策略模式、模板方法等
高内聚、低耦合,且兼顾灵活与性能。

模式总结

Thread:
适配器(适配Runnable)
模板方法(run()定制)
JUC:
单例、工厂(线程池创建)
策略(拒绝策略)
装饰器(FutureTask)
观察者(CompletableFuture)
代理(ExecutorService)
状态(线程池状态)
建造者(复杂配置)
工作窃取(ForkJoinPool)
读写锁(ReentrantReadWriteLock)

相关文章:

  • MCU-SDRAM-W9825G6KH的存储单元
  • Vue 文件下载功能的跨域处理与前后端实现详解
  • python: DDD using postgeSQL and SQL Server
  • 【STM32】STM32系列产品以及新手入门的STM32F103
  • 深度学习PyTorch之13种模型精度评估公式及调用方法
  • 头歌作业-数据库实验一:数据库和数据表的建立,修改和删除
  • 大模型——使用 Embedding 模型和向量数据库的 Spring AI RAG
  • Linux下磁盘读写流
  • 《几何原本》命题I.12
  • API和SDK
  • 护照阅读器在汽车客运站流程中的应用
  • Excel表格打印 第二页边框隔断
  • 在Spring Boot + MyBatis中优雅处理多表数据清洗:基于XML的配置化方案
  • Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(5)
  • #如何改变怂怂懦弱的气质(2)
  • 【Linux内核系列】:进入文件系统的世界
  • µCOS-III从入门到精通 第七章(任务调度)
  • 算法日记34:14届蓝桥C++B接龙数列(动态规划DP)
  • 安全见闻之网络安全新兴术语
  • ThreadLocal
  • 微信优惠群怎么做网站/seo文章生成器
  • 软件项目管理软件/seo技术培训教程视频
  • 网站建设具体需求/免费b站推广网站
  • 中企动力制作的网站/如何发布自己的网站
  • 网站策划的重要性/百度站长工具网站提交
  • 做音乐头像网站/优化神马网站关键词排名价格