为什么多个线程不可能同时抢到一把锁_并发基础理论:原子性问题、锁、管程...

我们再回顾一下,原子性问题的根源是CPU切换线程执行指令所导致的,当前一个对共享变量的操作没有完成之前,CPU又切换到另外一个线程来操作对应的共享变量,那么最终产生的结果就可能出现问题。

比如如果现在有两个线程都在执行number=number+1,他们最终的结果可能还是为1,因为PU执行流程可能会如下,:

4e04d48a5ae05027c3ed08e365b15e3c.png

如解决原子性问题

从上面的案例看,原子性问题的丢失完全是因为CPU切换线程执行指令导致的,那么是否意味着只要禁止CPU切换线程执行指令就可以呢,结果是行不通的,禁止CPU切换指令在单核CPU的确可以解决这个问题,但是多核CPU的场景下,CPU可以同时调度多个线程执行指令,那么该问题还是存在的。

所以我们必须另找出路,回过头来思考,我们会发现一个共性,就是不管是线程切换还是多核CPU同时执行指令,其实根本原因就是,对于共享变量在修改操作,在一个线程没有完成之前,另外一个线程是可以同时介入操作,所以才会导致一个线程的结果可能被另外一个线程覆盖。如果从这个角度来考虑的话,那么是不是只要达成一个线程在操作共享变量的过程中,另外一个线程是不能介入操作,只有等前面一个线程执行完之后,后面的线程才可以操作,也就是让两个线程对于共享变量的操作是互斥的,那么问题就可以解决,而让两个线程操作互斥我们常用的手段就是“加锁”。

互斥锁

能保证多个线程(进程、操作者)对于共享变量(共享资源)的操作是互斥的也就是我们常说的“互斥锁”,锁是一个通用的概念在很多领域都有锁的机制、使用锁的目的也很简单,就是“保证操作的原子性”。

锁这个名字虽然很形象,但是类比到我们现实世界往往容易造成困惑,比如现实世界的门锁,我们开门的必须是用钥匙,而不是需要获取锁,而且现实世界一个锁会有多个钥匙,这在编程领域是不允许的,所以我更愿意把锁的意思解释成“使用权”。每个操作者需要操作共享资源时,必须首先获得这个共享资源的使用权才可以进行操作,而当一个人拥有了共享资源的使用权之后,另外一个人是想要操作共享资源就之后就只能等待前者操作结束后释放共享资源的使用权。

当我们对某个共享资源加锁之后,如果线程想要访问共享资源,那么它首先要拿到这个对象的锁,当某一个线程获取到锁时,它便可以访问共享资源, 没有获取到锁的线程只能等待,直到上一个线程执行完毕之后释放锁再进行下轮锁的竞争,因为只有一把锁,所以永远只会有一个线程操作该资源。加了锁之后那么最后执行的流程就如下:

c6821481d734e2531da7192342ec0f1b.png

管程模型

使用互斥锁是为了线程杜宇共享资源的互斥性,对于共享资源的操作只允许有一个线程进行。但是在锁的获得与释放线程之间需要如何进行配合和协调又是一个问题,这也就是线程“同步”问题,所以解决共享变量的访问过程的原子性其实需要解决两个问题,一个是线程之间的互斥,二是线程之间的协调同步。对于这两个问题计算机领域有有一种成熟的方法论来解决,它就是管程。

管程是一个抽象的概念模型,为了解决多个进程或线程同时访问一个共享资源时能达到"互斥"和"同步"的效果,,它定义了管理共享资源的访问过程的模型,任何语言都可用通过都可以通过这套模型编写出安全的并发程序,管程实现必须达到下面几点要求

1、管程中的共享变量对于外部都是不可见的,只能通过管程才能访问对应的共享资源(意思是共享变量的操作必须通过管程,无法通过其他途径操作)。

2、管程是互斥的,某个时刻只能允许一个进程或线程访问共享资源(线程对于管程的访问是互斥的)。

3、管程中需要有线程等待队列和相应等待和唤醒操作(没获得锁的线程放入一个队列中等待,等前一个线程释放锁后可以通过某种机制唤醒等待队列中的线程)。

4、必须有一种办法使进程无法继续运行时被阻塞(在程序要求的逻辑条件不满足的时候,可以使其阻塞)。

我们来理解下上面几个条件:

首先第1点 和第2点我们都能理解,只能通过管程访问共享资源,并且每次只能有一个线程获得管程的执行权,这两个要求理解起来很简单,其实就是为了让线程之间达到互斥的效果。

然后看第3点要求,管程中要有等待队列和响应的等待和唤醒操作,这个也好理解,等待队列和唤醒可以使线程之间达到同步有序的执行。

第4点是比较让人费解的,什么时候线程会无法继续运行呢?为什么要在这个时候提供线程可以进入阻塞的方法。

咱们看一个案例:

场景:假如我们正在开发一个互联网项目;

角色:项目参与人员有产品经理、开发人员、测试人员参与;

限制:只有一个办公室可以使用,一个办公室一次只能容纳一个角色进入。

节点: 每个角色负责对应的节点,产品经理产品文档、开发人员产出项目代码、测试人员测试代码质量、产品进行验收。

条件:开发人员必须有了产品文档之后再产出项目代码、测试人员在开发人员开发完毕了之后进入测试、产品人员在测试完毕了之后进行验收。

d4e709c0f1631b40ad19101969ae4116.png

在这个场景里面,多个角色就是系统的多个线程,办公室是一个共享资源同一时刻只能有一个角色进入,这个场景里面就有一个阻塞场景,就是当一个开发人员抢到了办公室钥匙之后,进入到办公室,结果发现产品的需求都没有出来,这个时候开发人员是没有办法进行工作的,所以只能一直等,等到有产品文档之后继续下一步,但是这个时候产品是没办法进入办公室工作的,因为锁在开发人员手里,所以开发人员一直等不到需求文档,而产品经理一直进入不了办公室,导致死锁。

那么这里就需要有一种方式,当开发人员发现条件不成立的时候,此时开发人员可以主动的放弃办公室的锁,然后告诉办公室门口的产品经理,让产品经理先进办公室完成工作,开发人员自己则进入一个等待队列,当产品经理完成了工作之后,产品经理通知开发人员,然后自己放弃房间钥匙,等待需求验收再开始下一轮的工作。

最后以这种条件阻塞的方式让获得锁的线程可以主动让出锁,并等待其他线程唤醒再来检测条件,避免了某一个线程因为条件不满足导致任务无法进行,而因为别的线程无法进入到管程里,导致这个条件永远也无法改变锁造成的死锁问题。

下面这张图虽然不严谨,但是有助于你理解整个管程模型:

552f15b235b080e5edb5d04ea51efa6e.png

JAVA中的管程

通过上面的管程我们再来看JAVA里面的管程,JAVA是通过Synchronized关键字,和wait()、notify、notifyAll() 方法实现了整个管程模型, 与上面标准的管程模型不同的是,JAVA的Monitor属于一种简单的管程模型,因为它并没有使用多个条件变量的队列,不管是竞争锁产生的阻塞,还是拿到锁因为某个条件不合格导致的阻塞,统一都放入一个队列了。

下面我们同样通过一张图来理解:

09f19ea2d7437af41057767006748ca4.png

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

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

相关文章

继智能手机之后,增强现实如何再次改变我们与世界的交互方式

来源:资本实验室作为面向未来的新技术,增强现实和虚拟现实在过去几年中的发展可以用不温不火来形容。尽管创业投资和市场规模都在不断扩大,但硬件设备、数据传输速度、沉浸式体验效果、分辨率等因素都制约着该技术的快速发展,而大…

简要说明建设城市大脑三条关键标准规范

作者:刘锋 前言:简要的说,城市大脑不是一个城市级AI信息系统,也不是城市内部的信息化建设,而是互联网结构从网状模型向大脑模型进化时,与城市建设结合的产物,因此建设城市大脑需要拥有三个特征…

git恢复删除前的版本

有时候我们想撤销上一次提交,于是执行git reset --soft HEAD^,这样就成功的删除了你上一次的commit。但有时候发现不小心撤销错了,想把刚刚的撤销给撤回: 方法:首先执行git reflog 这时会显示刚刚各个操作&#xff0…

NLP模型超越人类水平?你可能碰到了大忽悠

大数据文摘出品来源:thegradient编译:张睿毅、武帅、钱天培一个军方训练的神经网络声称可以分类图像中的坦克,但实际上,它只是学会了识别不同的亮度,因为一种类型的坦克仅出现在明亮的图片中,而另一种类型仅…

伸缩杆怎么缩回去图解_没有阳台怎么晾衣服?这10个神器,让家里衣物晾晒更轻松方便...

没有阳台怎么晾衣服?这10个神器,让家里衣物晾晒更轻松方便!衣物晾晒是居家生活的必要环节,每个家庭在洗完衣物后都有自己的晾晒方式,但多数家庭会选择在阳台里进行。然而,对于没有阳台的家庭来说&#xff0…

小脑过度活跃,会引起整个大脑的问题

来源:中国生物技术网 9月10日,发表在《Cell Reports》的一项研究中,来自日本京都大学的研究团队发现小脑中的免疫活性诱导动物的神经元过度兴奋,干扰了精神运动行为。位于颅骨下背部的小脑,在调节诸如平衡、运动学习和…

Kubernetes(K8S)快速入门

概述 在本门课程中,我们将会学习K8S一些非常重要和核心概念,已经操作这些核心概念对应组件的相关命令和方式。比如Deploy部署,Pod容器,调度器,Service服务,Node集群节点,Helm包管理器等等。 在…

学会怎样使用Jsp 内置标签、jstl标签库及自定义标签

学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签。 jsp标签的分类:1)内置标签&am…

没有精准定位,万物还能实现互联吗?

来源:CSDN万物皆备,静待互联。这是一个万物都被赋予「生命」的时代,从人工流水线到工业自动化;从相互独立的设备到实时可监测相连的家居智能化;从汽车的复杂操作到自动驾驶的无人化......探索其真谛,实则科…

log4net保存到数据库系列二:独立配置文件中配置log4net

园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志一、WebConfig中配置log4net 一、WebConfig中配置log4net二、独立配置文件中配置log4net三、代码中xml配置log4net四、完整代码配置log4net五、新增数据库字…

科学界5个终极难题,如果有一个被解决,人类文明将升级

来源:科学杂志 纵观人类发展历史,似乎每到了一定的阶段学术界就会有重大难题出现,例如人类的起源问题。为此有科学家总结出了人类历史上五大终极难题,如果有一个问题被解决的话,那么人类文明会实现质的飞跃。在人类文明…

判断三个数是否能构成三角形_三角形的面积

问题描述:输入三角形三边长a,b,c(保证能构成三角形),输出三角形面积。输入:一行三个用一个空格隔开的实数a,b,c,表示三角形的三条边长。输出:输出三角形的面积,答案保留四位小数。样例输入3 4 5&#xff0c…

联合国2019数字经济报告

来源 : 数据观近日,联合国发布了《2019年数字经济报告》(以下简称《报告》)。报告指出,全球数字经济活动及其创造的财富增长迅速,且高度集中在美国和中国。《报告》称,美国和中国目前占有超过75…

【人工智能】人类该如何看待人工智能的“诗与远方”?

来源:智能制造网【导读】如今,在继传统行业的应用“钱”景爆发之后,人工智能又开启了对“诗与远方”的追逐。9月8日,华为推出了一款全新的AI诗人——“乐府”,据悉其能够驾驭和写作唐诗宋词等多种形式的诗词&#xff0…

centos6.5安装配置zabbix3.0.3

1.首先要准备LAMP环境。 (1)安装phpZabbix 3.0对PHP的要求最低为5.4,而CentOS6默认为5.3.3,完全不满足要求,故需要利用第三方源,将PHP升级到5.4以上rpm -ivh http://repo.webtatic.com/yum/el6/latest.rpm …

mysql数据对象

学习目标:了解掌握常见的几种数据库对象学会如何创建具体的数据对象mysql 常见的数据对象有哪些:DataBase/SchemaTableIndexView/Trigger/Function/Procedure多Database用途:业务的隔离资源的隔离表上的常用数据对象:索引约束视图&#xff0c…

赛迪研究院发布《2019量子计算发展白皮书》

来源:赛迪智库经国务院正式批准,由湖南省人民政府、工业和信息化部联合主办,中国电子信息产业发展研究院(简称“赛迪研究院”)、湖南省工业和信息化厅、长沙市人民政府承办的“2019世界计算机大会”在长沙召开。赛迪智…

安卓虚拟摄像头_iPhone 的「第四颗摄像头」位置,为什么给了激光雷达?

一个,两个,三个,四个…… 旗舰手机摄像头从 2016 年开始,以大约每年 1 个摄像头的数量在增长,有人调侃说麻将「八筒」将是所有智能手机摄像头的终极归宿。今年全新一代 iPhone 发布前,不少人推测 iPhone 12…

关于边缘计算和边云协同,看这一篇就够了~

来源:Deloitte物联网智库 编译导 读几年前,大多数人都期望将物联网部署至云端,这的确可以给个人用户带来便捷的使用体验,但构建企业级的物联网解决方案,仍然需要采用云计算和边缘计算的结合方案。与纯粹的云端解决方案…

ospf hello时间和dead_网络工程师_思科 | OSPF由简到难,配合命令学

交换机工作原理:基于源mac学习,基于目的mac转发。路由器的工作原理:收到一个数据包,拆掉帧头,拆开ip包头,提取目的ip地址,查找自己的路由表,有路由,转发,没有…