• 如何使用设计模式优化并发编程?


    在我们使用多线程编程时,很多时候需要根据业务场景设计一套业务功能。其实,在多线程编程中,本身就存在很多成熟的功能设计模式,学好它们,用好它们,那就是如虎添翼了。今天我就带你了解几种并发编程中常用的设计模式。

    线程上下文设计模式

    我们不妨通过一个具体的案例,来看看到底在什么的场景下才需要上下文呢?

    在执行一个比较长的请求任务时,这个请求可能会经历很多层的方法调用,假设我们需要将最开始的方法的中间结果传递到末尾的方法中进行计算,一个简单的实现方式就是在每个函数中新增这个中间结果的参数,依次传递下去。代码如下:

    执行结果:

    除了以上这些方法,其实我们还可以使用ThreadLocal实现上下文。ThreadLocal是线程本地变量,可以实现多线程的数据隔离。ThreadLocal为每一个使用该变量的线程都提供一份独立的副本,线程间的数据是隔离的,每一个线程只能访问各自内部的副本变量。

    ThreadLocal中有三个常用的方法:set、get、initialValue,我们可以通过以下一个简单的例子来看看ThreadLocal的使用:

    接下来,我们使用ThreadLocal来重新实现最开始的上下文设计。你会发现,我们在两个方法中并没有通过变量来传递上下文,只是通过ThreadLocal获取了当前线程的上下文信息:

    运行结果:

    Thread-Per-Message设计模式

    Thread-Per-Message设计模式翻译过来的意思就是每个消息一个线程的意思。例如,我们在处理Socket通信的时候,通常是一个线程处理事件监听以及I/O读写,如果I/O读写操作非常耗时,这个时候便会影响到事件监听处理事件。

    这个时候Thread-Per-Message模式就可以很好地解决这个问题,一个线程监听I/O事件,每当监听到一个I/O事件,则交给另一个处理线程执行I/O操作。下面,我们还是通过一个例子来学习下该设计模式的实现。

    Worker-Thread设计模式

    这里的Worker是工人的意思,代表在Worker Thread设计模式中,会有一些工人(线程)不断轮流处理过来的工作,当没有工作时,工人则会处于等待状态,直到有新的工作进来。除了工人角色,Worker Thread设计模式中还包括了流水线和产品。

    假设一个物流仓库的物流分拣流水线上有8个机器人,它们不断从流水线上获取包裹并对其进行包装,送其上车。当仓库中的商品被打包好后,会投放到物流分拣流水线上,而不是直接交给机器人,机器人会再从流水线中随机分拣包裹。代码如下:

    总结

    平时,如果需要传递或隔离一些线程变量时,我们可以考虑使用上下文设计模式。在数据库读写分离的业务场景中,则经常会用到ThreadLocal实现动态切换数据源操作。但在使用ThreadLocal时,我们需要注意内存泄漏问题,在之前的讲解,我们已经讨论过这个问题了。

    当主线程处理每次请求都非常耗时时,就可能出现阻塞问题,这时候我们可以考虑将主线程业务分工到新的业务线程中,从而提高系统的并行处理能力。而 Thread-Per-Message 设计模式以及 Worker-Thread 设计模式则都是通过多线程分工来提高系统并行处理能力的设计模式。

  • 相关阅读:
    我与JAVA过七夕
    统一异常的处理方法
    element + vue 批量调后端接口loading显示
    “华为杯”第十六届中国研究生数学建模竞赛-C题:视觉情报信息分析
    小程序入门笔记(一) 黑马程序员前端微信小程序开发教程
    RTSPServer推流服务
    DAY 12 结构体 共用体 枚举02
    采写编杂志采写编杂志社采写编编辑部2022年第10期目录
    【EdgeBox-8120AI-TX2】Ubuntu18.04 + ROS_ Melodic + 星秒PAVO2单线激光 雷达评测
    Photoshop 2023 v24.7
  • 原文地址:https://blog.csdn.net/m0_71777195/article/details/126567969