资讯专栏INFORMATION COLUMN

并发学习笔记 (4)

shiguibiao / 2004人阅读

摘要:不剥夺条件进程已获得的资源,在末使用完之前,不能强行剥夺。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。按照顺序加锁是一种有效的死锁预防机制。这种机制存在一个问题,在中不能对同步块设置超时时间。

[tutorial site][1]

死锁 deadlock

死锁是指两个或两个以上的进程在执行过程中,因竞争资源而造成的一种互相等待的现在,若无外力作用,它们都无法推进下去。

再重提下竞态条件

  

竞态条件(race condition),从多线程间通信的角度来讲,是指两个或多个线程共享的数据进行读或写的操作时,最终的结果取决于这些线程的执行顺序的情况。
导致竞态条件的代码是关键区域

这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:

互斥条件:一个资源每次只能被一个进程使用。

请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

避免死锁的方法: 加锁顺序

当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。
如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。

Note: 按照顺序加锁是一种有效的死锁预防机制。但是,这种方式需要你事先知道所有可能会用到的锁, 并对这些锁做适当的排序,但总有些时候是无法预知的.

加锁时限

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

Note: 由于存在锁的超时,所以我们不能认为这种场景就一定是出现了死锁。也可能是因为获得了锁的线程(导致其它线程超时)需要很长的时间去完成它的任务。

此外,如果有非常多的线程同一时间去竞争同一批资源,就算有超时和回退机制,还是可能会导致这些线程重复地尝试但却始终得不到锁。

这种机制存在一个问题,在 Java 中不能对 synchronized 同步块设置超时时间。你需要创建一个自定义锁

死锁检测

死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64367.html

相关文章

  • Java 并发学习笔记(二)

    摘要:请参看前一篇文章并发学习笔记一原子性可见性有序性问题六等待通知机制什么是等待通知机制当线程不满足某个条件,则进入等待状态如果线程满足要求的某个条件后,则通知等待的线程重新执行。经极客时间并发编程实战专栏内容学习整理 请参看前一篇文章:Java 并发学习笔记(一)——原子性、可见性、有序性问题 六、等待—通知机制 什么是等待通知—机制?当线程不满足某个条件,则进入等待状态;如果线程满足要...

    zgbgx 评论0 收藏0
  • 并发学习笔记 (6)

    摘要:每个通过网络到达服务器的连接都被包装成一个任务并且传递给线程池。线程池的线程会并发的处理连接上的请求。用线程池控制线程数量,其他线程排队等候。实现包,线程池顶级接口是但是严格意义讲并不是一个线程。此线程池支持定时以及周期性执行任务的需求。 tutorial site1tutorial site2 一个问题: 每启动一个新线程都会有相应的性能开销(涉及到OS的交互:创建线程,销毁线程...

    superw 评论0 收藏0
  • 《深入理解java虚拟机》学习笔记系列——垃圾收集器&内存分配策略

    摘要:虚拟机所处的区域,则表示它是属于新生代收集器还是老年代收集器。虚拟机总共运行了分钟,其中垃圾收集花掉分钟,那么吞吐量就是。收集器线程所占用的数量为。 本文主要从GC(垃圾回收)的角度试着对jvm中的内存分配策略与相应的垃圾收集器做一个介绍。 注:还是老规矩,本着能画图就不BB原则,尽量将各知识点通过思维导图或者其他模型图的方式进行说明。文字仅记录额外的思考与心得,以及其他特殊情况 内存...

    calx 评论0 收藏0
  • Java 并发学习笔记(一)——原子性、可见性、有序性问题

    摘要:最后,总结一下,导致并发问题的三个源头分别是原子性一个线程在执行的过程当中不被中断。可见性一个线程修改了共享变量,另一个线程能够马上看到,就叫做可见性。 计算机的 CPU、内存、I/O 设备的速度一直存在较大的差异,依次是 CPU > 内存 > I/O 设备,为了权衡这三者的速度差异,主要提出了三种解决办法: CPU 增加了缓存,均衡和内存的速度差异 发明了进程、线程,分时复用 CP...

    Chao 评论0 收藏0
  • Go语言核心36讲(Go语言实战与应用十二)--学习笔记

    摘要:除此之外,把并发安全字典封装在一个结构体类型中,往往是一个很好的选择。请看下面的代码如上所示,我编写了一个名为的结构体类型,它代表了键类型为值类型为的并发安全字典。在这个结构体类型中,只有一个类型的字段。34 | 并发安全字典sync.Map (上)我们今天再来讲一个并发安全的高级数据结构:sync.Map。众所周知,Go 语言自带的字典类型map并不是并发安全的。前导知识:并发安全字典诞生...

    不知名网友 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<