摘要:本文首发于掘金对于初次接触线程同步的前端来说,总是对互斥锁条件变量信号量等术语傻傻分不清楚,这里根据自己的理解简单做下总结,如有疏漏之处,欢迎大家批评指正。
本文首发于:掘金
对于初次接触线程同步的前端来说,总是对互斥锁、条件变量、信号量等术语傻傻分不清楚,这里根据自己的理解简单做下总结,如有疏漏之处,欢迎大家批评指正。
互斥锁在多线程环境中往往存在因某一资源被同时访问导致该资源不一致的问题,互斥锁 通过排它性,即同时只允许一个访问者对其进行访问来保证资源的有效同步,但它无法限制线程对该资源的访问顺序,因此线程对资源的访问也是无序的。
自旋锁在互斥锁中,如果线程 A 在请求锁的时候发现该锁已被线程 B 霸占,那么此时线程 A 便会进入休眠状态,直到锁被线程 B 释放后被系统唤醒。但在自旋锁中,线程 A 在发现锁被霸占时并不进入休眠,而是一直循环查看锁的持有者是否已经释放了该锁。初看起来,这种霸占CPU资源的做法极其低效,但与互斥锁仔细对比后我们可以发现它有以下几个优点:
实现简单:只需死循环检测锁状态即可,没有互斥锁休眠、唤醒所涉及的一系列上下文切换、CPU抢占等各种复杂流程。
高效:正是由于实现极其简单,所以它在一些情况下极其高效。
当然,上面的高效也是有条件的,由于它占用CPU资源,所以它主要适用于以下场景:
临界区持锁时间较短且CPU资源不紧张。
多用于多核环境。
递归锁递归锁又叫可重入锁,与 互斥锁的主要区别是在同一个线程内可以多次获得锁资源,别的线程必须等待该线程释放相应次数的锁才能获得,其主要目的是为了解决同一进程内的死锁问题,但在不同的线程中,它与互斥锁并没有什么区别。
读写锁上面介绍的互斥锁、自旋锁、递归锁都属于排它锁,即一个线程获得锁资源后,其他线程必须等待直到该锁被释放。但在某些读多写少的情况下,这样的机制难免有些低效,因此读写锁就是为解决这样的问题而诞生的。读写锁分读锁和写锁,其特点如下:
读锁:如果线程 A 获得了读锁,线程 B 可以获得读锁,但不可以获得写锁。
写锁:如果线程 A 获得了写锁,线程 B 即不可以获得读锁,也不可以获得写锁。
写锁优先:如果线程 A 申请获得写锁,线程 B 申请获得读锁,优先给线程 A 分配写锁。
条件变量条件变量主要适用于一个线程需要等待某个共享资源满足某个条件后进行一系列同步操作的场景。它主要包含:
等待某个条件成立的等待线程。
满足某个条件成立的信号发送线程。
它一般与互斥锁配合使用(主要用来保护共享资源),在等待线程中,如果条件不成立,该线程会自动阻塞,并释放掉等待状态改变的互斥锁,如果信号发送线程改变了条件,它发送信号给关联的条件变量,并唤醒等待线程,等待线程重新获得互斥锁,重新评估条件。
信号量信号量主要适用于一个线程需要等待另外一个个线程完成一些操作后再继续执行自己操作的场景,它与上面各种锁的最大区别是:
锁要解决的是共享资源的同步问题,而信号量要解决的是线程之间任务同步问题。
锁必须在同一进程进行加锁和解锁操作,而信号量可以通过一个线程中得到,在另一个线程中释放。
认真回味下我们会发现信号量要解决的问题也可以使用条件变量来处理,相对于信号量,条件变量主要有以下不足:
条件变量需要借助全局共享变量以及互斥锁来达到状态的检测。
条件变量适用于多线程环境,无法适用于多进程环境。
屏障屏障是一种协调多个线程进行工作,即允许某个线程等待直到所有的合作线程达到某一个条件,然后从该条件下继续执行的同步机制。
总结本文对线程同步中所涉及到的术语的特点及适用场景进行了简单的总结,如果你在阅读过程中发现任何错误,欢迎留言指正,我们一起学习一起进步。^ _ ^
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/35703.html
摘要:当某个不应该发布的对象被发布时,这种情况被称为逸出。线程安全共享线程安全的对象在其内部实现同步,因此多线程可以通过对象的公有接口来进行访问而不需要进一步的同步。 前言 本系列博客是对《Java并发编程实战》的一点总结,本篇主要讲解以下几个内容,内容会比较枯燥。可能大家看标题不能能直观的感受出到底什么意思,这就是专业术语,哈哈,解释下,术语(terminology)是在特定学科领域用...
摘要:,锁定,所用于主内存变量,它把一个变量标识为一条线程独占的状态。并发编程中的根本问题以及提供的解决方案整个并发编程所遇到的问题可以说是以下三个问题的变种。下篇预告多线程与锁此致,敬礼 该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,...
摘要:本文探讨并发中的其它问题线程安全可见性活跃性等等。当闭锁到达结束状态时,门打开并允许所有线程通过。在从返回时被叫醒时,线程被放入锁池,与其他线程竞争重新获得锁。 本文探讨Java并发中的其它问题:线程安全、可见性、活跃性等等。 在行文之前,我想先推荐以下两份资料,质量很高:极客学院-Java并发编程读书笔记-《Java并发编程实战》 线程安全 《Java并发编程实战》中提到了太多的术语...
摘要:线程可以处于以下状态之一尚未启动的线程处于此状态。被阻塞等待监视器锁定的线程处于此状态。无限期等待另一个线程执行特定操作的线程处于此状态。已退出的线程处于此状态。调用的线程处于状态,以使指定的线程终止。 Java Thread 可能处在以下几种状态 Java Doc 里通过一个枚举类型 Enum 来定义。 线程可以处于以下状态之一:showImg(https://segmentfaul...
阅读 3771·2021-11-24 09:38
阅读 1725·2021-11-17 09:33
阅读 1056·2021-10-19 11:42
阅读 1686·2021-10-14 09:42
阅读 2055·2019-08-30 15:44
阅读 436·2019-08-30 14:04
阅读 2781·2019-08-30 13:13
阅读 1778·2019-08-30 12:51