三九宝宝网宝宝教育学龄段教育

死锁避免检测和预防之间的区别是什么

01月26日 编辑 39baobao.com

[社会认知中错误有哪些?我们怎样去避免]社会认知 又称“社会知觉”或“人际知觉”,指对社会 客体的知觉过程,是一种基本的社会心理活动。社会 认知主要包括以下几种类型:(一)对他人的认知:指对他人表情的认知和对他人人...+阅读

在有些情况下死锁是可以避免的。本文将展示三种用于避免死锁的技术:加锁顺序加锁时限死锁检测加锁顺序当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。看下面这个例子:Thread 1: lock A lock BThread 2: wait for A lock C (when A locked)Thread 3: wait for A wait for B wait for C如果一个线程(比如线程3)需要一些锁,那么它必须按照确定的顺序获取锁。

它只有获得了从顺序上排在前面的锁之后,才能获取后面的锁。例如,线程2和线程3只有在获取了锁A之后才能尝试获取锁C(译者注:获取锁A是获取锁C的必要条件)。因为线程1已经拥有了锁A,所以线程2和3需要一直等到锁A被释放。然后在它们尝试对B或C加锁之前,必须成功地对A加了锁。按照顺序加锁是一种有效的死锁预防机制。但是,这种方式需要你事先知道所有可能会用到的锁(译者注:并对这些锁做适当的排序),但总有些时候是无法预知的。

加锁时限另外一个可以避免死锁的方法是在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行(译者注:加锁超时后可以先继续运行干点其它事情,再回头来重复之前加锁的逻辑)。

以下是一个例子,展示了两个线程以不同的顺序尝试获取相同的两个锁,在发生超时后回退并重试的场景:Thread 1 locks AThread 2 locks BThread 1 attempts to lock B but is blockedThread 2 attempts to lock A but is blockedThread 1's lock attempt on B times outThread 1 backs up and releases A as wellThread 1 waits randomly (e.g. 257 millis) before retrying.Thread 2's lock attempt on A times outThread 2 backs up and releases B as wellThread 2 waits randomly (e.g. 43 millis) before retrying.在上面的例子中,线程2比线程1早200毫秒进行重试加锁,因此它可以先成功地获取到两个锁。

这时,线程1尝试获取锁A并且处于等待状态。当线程2结束时,线程1也可以顺利的获得这两个锁(除非线程2或者其它线程在线程1成功获得两个锁之前又获得其中的一些锁)。需要注意的是,由于存在锁的超时,所以我们不能认为这种场景就一定是出现了死锁。也可能是因为获得了锁的线程(导致其它线程超时)需要很长的时间去完成它的任务。

此外,如果有非常多的线程同一时间去竞争同一批资源,就算有超时和回退机制,还是可能会导致这些线程重复地尝试但却始终得不到锁。如果只有两个线程,并且重试的超时时间设定为0到500毫秒之间,这种现象可能不会发生,但是如果是10个或20个线程情况就不同了。因为这些线程等待相等的重试时间的概率就高的多(或者非常接近以至于会出现问题)。

(译者注:超时和重试机制是为了避免在同一时间出现的竞争,但是当线程很多时,其中两个或多个线程的超时时间一样或者接近的可能性就会很大,因此就算出现竞争而导致超时后,由于超时时间一样,它们又会同时开始重试,导致新一轮的竞争,带来了新的问题。)这种机制存在一个问题,在Java中不能对synchronized同步块设置超时时间。

你需要创建一个自定义锁,或使用Java5中java.util.concurrent包下的工具。写一个自定义锁类不复杂,但超出了本文的内容。后续的Java并发系列会涵盖自定义锁的内容。死锁检测死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。

除此之外,每当有线程请求锁,也需要记录在这个数据结构中。当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。例如,线程A请求锁7,但是锁7这个时候被线程B持有,这时线程A就可以检查一下线程B是否已经请求了线程A当前所持有的锁。如果线程B确实有这样的请求,那么就是发生了死锁(线程A拥有锁1,请求锁7;线程B拥有锁7,请求锁1)。

当然,死锁一般要比两个线程互相持有对方的锁这种情况要复杂的多。线程A等待线程B,线程B等待线程C,线程C等待线程D,线程D又在等待线程A。线程A为了检测死锁,它需要递进地检测所有被B请求的锁。从线程B所请求的锁开始,线程A找到了线程C,然后又找到了线程D,发现线程D请求的锁被线程A自己持有着。这是它就知道发生了死锁。下面是一幅关于四个线程(A,B,C和D)之间锁占有和请求的关系图。

像这样的数据结构就可以被用来检测死锁。那么当检测出死锁时,这些线程该做些什么呢?一个可行的做法是释放所有锁,回退,并且等待一段随机的时间后重试。这个和简单的加锁超时类似,不一样的是只有死锁已经发生了才回退,而不会是因为加锁的请求超时了。虽然有回退和等待,但是如果有大量的线程竞争同一批锁,它们还...

以下为关联文档:

夏季如何避免食物中毒◆ 好饭好菜应立即吃掉,食用的常温下已存放4小时-5小时煮过的食物是最危险,因为许多有害细菌在常温下可大量繁殖扩散。 ◆ 未经烧煮的食品通常有可诱发疾病的病原体,因此,食物必...

如何避免兔唇的发生可以到正规的医院或药店购买“叶酸”,在孕前三个月至孕早期的三个月服用,可以预防“兔唇”发生。 在饮食中,也可以多吃一些富含叶酸的食物,蔬菜(尤其是绿叶蔬菜)中含有较多的叶酸...

避免食用哪些对生育有害的食物呢有些饮食,虽然美味,但多食容易损害卵子和精子,因而要食用。 (一) 吃过多熟食成品会导致不孕 很多熟食味道鲜美、香辣诱人,主要就是因为在制作过程中添加了耵 多添加剂,如固化剂、抗...

大家有什么好方法避免出生缺陷避免出生缺陷三部曲 想要一个健康的宝宝,夫妇双方的身体健康十分重要,并且,事先便要为宝宝的到来做好一切准备,有计划地怀孕,做好准妈咪的孕期保健和检查。才能最大限度地避免出...

怎样避免新生儿的出生缺陷首先要避免近亲结婚、避免致病微生物感染和有害物质;其次要在孕前进行优生遗传咨询、加强营养、增强免疫力、进行致病微生物检查,把握良好受孕时间计划怀孕;最后要在孕期避免诱...

常见出生缺陷如何预防和避免唐氏综合症: 面容特殊 智力低下 唐氏综合症是小儿染色体病中最常见的一种,也叫先天愚型。唐氏综合症的孩子面部特征比正常孩子显得“古怪”:眼间距宽、眼睛小而上挑、鼻梁扁平...

哪些方法可以避免出生缺陷呢?哪些方法可以避免出生缺陷呢如何预防出生缺陷呢?我们都想看到小宝宝健康的出生,但是有些家庭的孩子却出现了异常的情况,这让我们的家长非常的苦恼。今天我们就和大家来来了出生缺陷的问题,也就是我们常说的...

有没有一个永不崩溃的浏览器避免有时打开网页时冷不丁冒出IE浏用世界之窗吧 IE浏览器是系统的,没法删,把世界之窗设为默认浏览器就是默认跳出世界之窗了,偶尔会跳出IE,但基本是一些不常用软件点击才弹出IE, 浏览器不崩溃是不可能的,网页或多...

如何正确避免过敏体质呢过敏体质,主要是来自于遗传因素,加上外界过敏原或刺激物(如尘螨、过敏蛋白质、空气污染或病毒感染)的激发,导致皮肤、呼吸道和肠道出现水肿、发炎、气管平滑肌和肠道出现收缩、痉...

推荐阅读
图文推荐