Java多线程基础知识-3

news2024/11/27 2:14:51

ReentrantLock:

  • condition.await()方法之前必须调用lock.lock()代码获取同步监视器。
  • 类比:
    • Object类中的wait()相当于Condition类中的await()
    • Object类中wait(long timeout)相当于Condition类中await(long time, TimeUnit unit)方法
    • Object类中notify()相当于Condition类中的signal()
    • Object类中notifyAll()相当于Condition类中的signalAll()
  • 使用多个Condition实现通知部分线程,注意signalAll()会通知使用condition的所有方法,如果这种场景是错误的,请多申请几个lock.newCondition()
  • condition本质是不同的等待队列。

ReadWriteLock:

  • 读读共享、写写互斥、读写互斥、写读互斥

JUC中常见类:

LongAdder:

  • LongAdder是JDK1.8新增的一个原子性操作类;
  • 内部维护base变量+Cells数组 --> 减小争夺共享资源的并发量;
  • 惰性加载:一开始没有空间时,所有的更新都是操作base变量,在需要时候再创建Cells --> 减小内存空间的使用;
  • 伪共享 :Cells的原子性数组元素彼此相邻存放共享缓存行-->提高性能。

见com.hanxiaozhang.threadbase1ndedition.no5juccommonclass.No1LongAdder

CountdownLatch( 门闩,闭锁):

  • 它可以使一个线程等待其他线程完成各自的工作后再执行;
  • 内部继承AQS类实现的;
  • 原理:它通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1;当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

见com.hanxiaozhang.threadbase1ndedition.no5juccommonclass.No2CountDownLatch

CyclicBarrier(循环栅栏):

  • 它可以让一组线程到达一个屏障点的时被阻塞,直到最后一个线程到达屏障点才开启,继续往下执行。
  • 原理:CyclicBarrier内部定义了一个Lock对象,每当一个线程调用await方法时,将拦截的线程数减1,然后判断剩余拦截数是否为初始值parties,如果不是,进入Lock对象的条件队列等待。反之(是),执行barrierAction对象的Runnable方法,然后将锁的条件队列中的所有线程放入锁等待队列中, 这些线程会依次的获取锁、释放锁。
  • 使用场景:领导开会、并发执行;
  • 使用场景举例:一个复杂的操作,包括数据库操作、网络操作、文件操作,必须等到三个线程同时结束才能继续进行。

见com.hanxiaozhang.threadbase1ndedition.no5juccommonclass.No3CyclicBarrier

Phaser (移相器):

  • 它把多个线程协作执行的任务划分为多个阶段,编程时需要明确各个阶段的任务,每个阶段都可以有任意个参与者,线程都可以随时注册并参与到某个阶段。

见com.hanxiaozhang.threadbase1ndedition.no5juccommonclass.No4Phaser

Semaphore (信号量):

  • 用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。
  • Semaphore是基于AQS接口实现的信号量模型。
  • 原理:AQS提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架,它利用了一个int来表示状态,通过类似acquire和release的方式来操纵状态。
  • 场景:限流、车道与收费站

见com.hanxiaozhang.threadbase1ndedition.no5juccommonclass.No5Semaphore

Exchanger(交换器):

  • 用于两个工作线程之间交换数据

见com.hanxiaozhang.threadbase1ndedition.no5juccommonclass.No6Exchanger

LockSupport(锁支持):

  • 线程阻塞工具类
  • park不需要获取某个对象的锁
  • 可以先调用unpark,然后调用park,结果是park不起作用,即可以说明park和unpark的使用不会出现死锁的情况
  • 中断的时候park不会抛出InterruptedException异常,所以需要在park之后自行判断中断状态,然后做额外的处理

见com.hanxiaozhang.threadbase1ndedition.no5juccommonclass.No7LockSupport

相关面试题:

CyclicBarrier当所有线程都到达屏障点后,等待线程的执行顺序是什么样的?

        CyclicBarrier的await方法是使用ReentrantLock和Condition控制实现的,使用的Condition实现类,是ConditionObject,它里面有一个等待队列和await方法,这个await方法会向队列中加入元素。当调用CyclicBarrier的await方法会间接调用ConditionObject的await方法,当屏障关闭后,首先执行指定的barrierAction,然后依次执行等待队列中的任务,有先后顺序。

CyclicBarrier和CountDownLatch的区别:

CDL的作用:使一个线程等待其他线程完成各自的工作后再执行;CB的作用:让一组线程到达一个屏障点的时候被阻塞,直到最后一个线程到达屏障点才开启,继续往下执行。

CDL允许一个或多个线程等待一组事件的产生;CB用于等待其他线程运行到栅栏位置。

CDL的计数器只能使用一次,减计数方式;CB的计数器可以使用reset()方法重置,可以使用多次(它能够处理更为复杂的场景),减计数方式。

CB提供了更多的方法,getNumberWaiting()获得阻塞的线程数量,isBroken()了解阻塞的线程是否被中断。

AbstractQueuedSynchronizer(AQS):

简介(AbstractQueuedSynchronizer):

        AQS是抽象的队列式同步和锁实现框架。它是除了java自带的synchronized关键字之外的锁机制。例如ReentrantLock、ReentrantReadWriteLock、Semaphore、FutureTask等都是基于AQS实现的。

原理(重要):

        如果被请求的共享资源空闲时,将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用时,则需要一套“线程阻塞等待以及被唤醒时锁分配”的机制,AQS是用CLH队列锁实现该机制,即将暂时获取不到锁的线程加入到队列中。

        简单说:AQS就是基于CLH队列,用volatile修饰资源计数器state,线程通过CAS机制去改变状态符waitStatus,成功则获取锁成功,失败则进入等待队列,等待被唤醒。

State(资源计数器)在不同类中的作用:

        ReentrantLock中实现锁的可重入、Semaphore中控制同时访问特定资源的线程数量、CountDownLatch中实现需要等待线程的数量。

CLH队列(自旋锁、同步队列):

        是一个FIFO的双向队列,AQS依赖它来完成同步状态的管理,CLH队列包含多个Node(AQS内部类)对象,每个节点(Node)表示一个线程,它保存着线程的引用(thread)、状态(waitStatus)、前驱节点(prev)、后继节点(next)、(条件队列中的后继节点)nextWaiter。

AQS图:

ConditionObject:

        实现了基于Lock锁下的线程通信机制,主要方法包括await()、signal()、signalAll()

使用:

        AQS使用了模板方法的设计模式,如果自定义同步器,只需继承AQS并重写指定方法(只要重写“获取”和“释放”共享资源的方法),而具体线程等待队列的维护,AQS在顶层已经实现好了。

需要重写几种方法:

  • isHeldExclusively():该线程是否正在独占资源(只有用到condition需实现)。
  • tryAcquire(int):独占方式,尝试获取资源。成功true,失败false。
  • tryRelease(int):独占方式,尝试释放资源。成功true,失败false。
  • tryAcquireShared(int):共享方式,尝试获取资源。负数失败;0成功,但没有剩余可用资源;正数成功,且有剩余资源。
  • tryReleaseShared(int):共享方式,尝试释放资源,如果释放后允许唤醒后续等待的结点返回true,否则返回false。

常用的方法:

  • acquire(int):独占模式的获取,忽略中断。
  • acquireInterruptibly(int):独占模式的获取,可中断
  • tryAcquireNanos(int, long):独占模式的获取,可中断,并且有超时时间。
  • release(int):独占模式的释放。
  • acquireShared(int):共享模式的获取,忽略中断。
  • acquireSharedInterruptibly(int):共享模式的获取,可中断。
  • tryAcquireSharedNanos(int, long):共享模式的获取,可中断,并且有超时时间。
  • releaseShared(int):共享模式的释放。

举例(ReentrantLock):

        ReentrantLock(可重入独占式锁):state初始化值为0,表示未锁定状态,A线程调用lock()时,会调用tryAcquire()独占锁并将state+1。之后其它线程再想调用tryAcquire()时就会失败,直到A线程调用unlock()使state=0为止,其它线程才有机会获取该锁。A释放锁之前,自己也是可以重复获取此锁,即state的值累加,这就是可重入的概念。

Tips:获取多少次锁就要释放多少次锁,保证state是能回到零态的。

资源共享方式:独占和共享

        独占锁模式:每次只能有一个线程持有锁,ReentrantLock就是以独占方式实现的互斥锁。

        共享锁模式:允许多个线程同时获取锁,并发访问共享资源,比如ReentrantReadWriteLock

ThreadLocal:

作用:

        提供线程内的局部变量,在多线程下访问时,保证各个线程里变量的独立性(独立的副本、线程私有的实例变量);它对外提供initialValue()、set(T value) 、T get()和remove() 四个方法,其中get、set、remove等方法都可以有清除key为null的Entry(cleanSomeSlots(int i, int n)),可以防止内存泄漏。

        见com.hanxiaozhang.threadbase1ndedition.no6threadlocal.No1ThreadLocal

原理(Hash底层用的数组,不是散列表):

        ThreadLocal定义一个了ThreadLocalMap(静态内部类)的哈希映射(数据结构),用于维护线程本地的变量值;ThreadLocalMap主要由一个Entry类型的数组组成,Entry的key为ThreadLocal本身,value为ThreadLocal对应的值,通过key.threadLocalHashCode & (table.length – 1)确定数组索引位置,如果该位置的key不对,再通过nextIndex()计算下一个索引位置,直到找到目标位置或为空的位置为止;它通过线性探查开放定址法减少hash冲突。每个线程都有一个ThreadLocalMap类型的threadLocals变量。

场景:

        在线程间隔离而在方法或类间共享的场景,多并发下存储用的登录信息,多数据源切换中当前数据源局部变量等(自己写过)。

ThreadLocal碰撞解决与神奇的 0x61c88647:

  • ThreadLocalMap使用基于线性探查(源码nextIndex()与prevIndex())开放寻址法(源码set(ThreadLocal key, Object value)中)的哈希表,这种方法可以减少碰撞;
  • 每次创建ThreadLocal实例时,哈希值都会累加 0x61c88647,目的是让哈希值能均匀的分布在2的N次方的数组里,减少碰撞;
  • Tips:取模方法(key.threadLocalHashCode & (table.length - 1))同HashMap。

ThreadLocal引发的内存泄露:

源码:static class ThreadLocalMap中的Entry

ThreadLocalMap使用ThreadLocal的弱引用作为Entry的key,如果ThreadLocal没有外部强引用,下一次系统GC时,ThreadLocal必然会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry。如果当前线程一直运行,并且一直不执行get、set、remove等方法(它们有清除key为null的Entry的功能),存在Thread Ref -> Thread -> ThreadLocalMap -> Entry -> value的强引用,导致这些key为null的Entry的value永远无法回收,造成内存泄漏。

避免内存泄漏:

在使用完ThreadLocal后,手动调用remove方法。

四种引用:

强引用:

  • 概念:创建一个对象并把这个对象赋给一个引用变量(对象引用),只要强引用还存在,GC永远不会回收掉被引用的对象。

见com.hanxiaozhang.threadbase1ndedition.no8fourreference.No1StrongReference

软引用:

  • 概念:用来描述一些还有用但并非必需的对象,使用SoftReference类来实现软引用。如果对象只具有软引用,内存空间足够,GC就不会回收它;如果内存空间不足了,GC就会回收这些对象的内存。只要GC没有回收它,该对象就可以被程序使用。
  • 场景: 缓存

见com.hanxiaozhang.threadbase1ndedition.no8fourreference.No2SoftReference

弱引用:

  • 概念:用来描述一些非必需对象的,使用WeakReference类来实现弱引用,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。在GC线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
  • 场景:一般用在容器中。

见com.hanxiaozhang.threadbase1ndedition.no8fourreference.No3WeakReference

虚引用:

  • 概念:是最弱的一种引用关系,使用PhantomReference类来实现虚引用,主要用来跟踪对象被垃圾回收器回收的活动。

见com.hanxiaozhang.threadbase1ndedition.no8fourreference.No4PhantomReference

并发容器:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1848840.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT基础 - 文件目录操作

目录 零. 简介 一. QDir 二. QFileSystemWatcher 三. 总结 零. 简介 在 QT 中,文件目录操作主要涉及到QDir类和QFileInfo类。 QDir类具有存取目录结构和内容的能力,可以操作目录、存取目录或文件信息、操作底层文件系统,还可以存取 Qt 的…

公司名称含有关商标名称可能涉及侵权!

有个朋友找到普推商标知产老杨,说有个人给他打电话,说他的公司名称侵权另一家的商标名称,让他要改下公司名称,不改就要告侵权,此前看到过许多,在一些省市注册公司时,如果公司名称与已注册商标相…

不懂就问,开通小程序地理位置接口有那么难吗?

小程序地理位置接口有什么功能? 若提审后被驳回,理由是“当前提审小程序代码包中地理位置相关接口( chooseAddress、getLocation )暂未开通,建议完成接口开通后或移除接口相关内容后再进行后续版本提审”,那么遇到这种情况&#x…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《含氢综合能源系统多目标最优折中分布鲁棒低碳调度》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

MLP多层感知器:AI人工智能神经网络的基石

MLP 是指多层感知器(Multilayer Perceptron),是一种基础人工神经网络模型(ANN,Artificial Neural Network)。MLP 的核心是通过深度学习从大量数据中学习特征和模式,并训练参数。通过参数与激活函…

高精度乘法的实现

这是C算法基础-基础算法专栏的第九篇文章,专栏详情请见此处。 引入 上次我们学习了高精度加法的实现,这次我们要学习高精度减法的实现。 高精度乘法与高精度加法的定义、前置过程都是大致相同的,如果想了解具体内容,可以移步至我的…

10.2 JavaEE——Spring MVC入门程序

要求在浏览器发起请求,由Spring MVC接收请求并响应,具体实现步骤如下。 一、创建项目 在IDEA中,创建一个名称为chapter10的Maven Web项目。 (一)手动设置webapp文件夹 1、单击IDEA工具栏中的File→“Project Structu…

【linux】shell脚本中设置字体颜色,背景颜色详细攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

通过开放解析智能分块提高 RAG 性能

如果要使用大型语言模型 ()LLMs 实现生成式 AI 解决方案,则应考虑使用检索增强生成 (RAG) 的策略来生成上下文感知提示LLM。在启用 LLM RAG 的预生产管道中发生的一个重要过程是删除文档文本,以便仅将文档中…

JupyterLab使用指南(八):更改JupterLab左侧默认打开目录

在JupyterLab中,默认打开路径通常是由其配置文件中的root_dir设置决定的。如果你没有特意设置这个配置项,JupyterLab可能会使用当前用户的主目录或者上一次关闭时的路径作为默认打开路径。 更改JupyterLab默认路径的操作在不同操作系统下大体相似&…

Apache Arrow 和数据的未来:开放标准推动人工智能发展

Apache Arrow 是一种开源列式内存格式,适用于平面数据和分层数据。在现代数据湖中,开放数据格式(如 Apache Arrow)位于现代对象存储的存储层中。这些格式成为对象存储中的对象。 在最新版本中,Apache Arrow 宣布计划从…

第二十七篇——通信趋势:5G和IOT的商机在哪里?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 借势的重要性,但是要做到借势,得先看到&#xff0…

WPF文本绑定显示格式StringFormat设置-特殊格式时间日期和多数据绑定

WPF文本绑定显示格式StringFormat设置 特殊格式设置日期/时间使用系统默认样式自定义格式: 绑定多个属性(多重绑定)多重绑定中的特殊字符示例: 特殊格式设置 在Textblock等文本控件中,我们经常要显示一些日期和时间&a…

Android (已解决)Execution failed for task ‘:app:lint‘

文章目录 一、错误原因二、解决方法 一、错误原因 这个错误信息表示在执行 Lint 检查时发现了错误,导致构建过程被中断。Lint 是一个用于检测 Android 项目中潜在问题的工具,比如性能、安全性、可用性等方面的问题。当Lint检查到严重错误时,…

碳钢酸洗线送酸槽蒸汽冷凝水PH计测量装置改进方法

碳钢酸洗线送酸槽蒸汽冷凝水PH计测量装置改进方法 一、项目提出前状况 1)立项背景 轧钢退火酸洗生产线的酸洗过程需要使用大量的硫酸、盐酸、硝酸、氢氟酸等酸液对钢带的表面进行清洗,酸洗过后产生较多的酸洗废水,酸洗废水需要经过处理达到污水排放标准后才能排放。其中酸…

Android企业级实战-界面篇-5

3.colors.xml文件内容(此案例可用) #ffb2b2b2 #ff14c4bc color/jimeng_text_tertiary_light color/jimeng_green_light color/jimeng_background_secondary_light color/jimeng_background_secondary_light #7f4eb7ba 4.strings.xml文件内容&…

Android系统揭秘(一)-Activity启动流程(上)

public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread (IApplicationThread) contextThread; … try { … int result …

React实现列表列宽可拖拽

1.中文文档上没有&#xff0c;英文文档上有&#xff08;这个老六&#xff01;&#xff01;&#xff09; <Tableborderedcomponents{{header: {cell: ResizableTitle,},}}columns{mergedColumns}dataSource{data} />React - Resizable column

20240622 每日AI必读资讯

&#x1f916;力压GPT-4o&#xff01;新王Claude 3.5 Sonnet来了&#xff0c;直接免费可用 - 新模型在推理、知识和编码能力评估方面超越了以前的版本和竞争对手GPT 4o模型&#xff0c;同时其运行速度是Claude 3 Opus的两倍。 - 该模型可在http://Claude.ai和Claude iOS应用上…

鸿蒙 登录界面示例

1.b站登录界面 我的b站教学视频&#xff1a;https://www.bilibili.com/video/BV1LQgQexEGm/https://www.bilibili.com/video/BV1LQgQexEGm/ 最终实现效果&#xff1a; 需要准备2张图片&#xff0c;分别是向下和向右边的图标 代码&#xff1a; Entry Component struct Index…