关于java:并发编程之临界区\阻塞\非阻塞\死锁\饥饿\活锁

35次阅读

共计 1544 个字符,预计需要花费 4 分钟才能阅读完成。

本文介绍并发编程中的若干概念,实际上在笔者之前的文章中,曾经介绍过很多概念。比方:并发与并行、同步与异步、锁与信号量等等。参考《并发编程专栏》,本文计息介绍一些绝对深刻一些的概念

一、临界区

为了不便大家了解,咱们先看上面的这样一张图,咱们能够把房子看作一个过程,每个房子外面的住户及其流动看作一个线程,饮水机、健身器材、厕所都属于共享资源。这里的共享资源理论就是临界区的概念 ,临界区的资源在同一时间只能被一个线程(住户) 应用,所以一旦临界资源被占用,其余的线程 (住户) 能做的就只有期待。

比方,在一个出租房内,住户 A 占用了厕所,在他应用厕所的这段时间内厕所这个资源就是他独占的。如果住户 B 此时也想上厕所,就只能期待住户 A 上完厕所之后才能够持续应用该资源。

二、阻塞和非阻塞

理解了临界区的概念之后,阻塞概念就好了解了。一个线程先占用了临界区的资源,此时如果其余的线程想应用临界区资源就必须期待。这种占用临界区资源,阻塞其余线程继续执行的状况就是线程阻塞(Blocking)。

然而 说到非阻塞,个别说的就是是否对以后线程本人产生阻塞,比方:

  • 我执行一个工作,比方应用饮水机接水。我拿了一个杯子接水,而我必须在饮水机后面等着水接完,这种就是阻塞式线程。
  • 如果我拿了杯子接水,把杯子放到饮水机上面,饮水机会在杯子接满水之后,主动对我收回异步告诉 (比方声音告警)。我 能够在此期间做其余的事件,这种就是非阻塞式线程(Non-Blocking)。非阻塞式线程,从编程的角度个别都是通过回调函数,或者响应式编程 (Reactive programming) 实现的。

三、死锁、饥饿和活锁

  • 死锁:咱们来看下面的这张图,在十字路口 A 车道的 A1 车像转向 B 车道,但 B 车道入口被 B1 车占用;在十字路口 B 车道的 B1 车像转向 C 车道,但 C 车道入口被 C1 车占用;在十字路口 C 车道的 C1 车像转向 D 车道,但 D 车道入口被 D1 车占用;在十字路口 D 车道的 D1 车像转向 A 车道,但 A 车道入口被 A1 车占用;也就是说:线程因为资源竞争,彼此须要资源又都无奈开释,导致线程无奈获取下一步执行所需的资源,导致死锁产生。

  • 饥饿:举个例子农民给小鸡喂食,如果有五只鸡每次都刚好给五只鸡的饲料量。无奈防止的是有的鸡吃的量超过布局量,最总导致某一只鸡无奈吃到足够的饲料。因为它无奈早退足够的饲料,它就比拟肥壮,抢食的能力弱。恶性循环,最终很可能被饿死。具体到编程层面,就是 某一线程 A 的优先级比拟低,而后优先级高的线程又常常占用资源不开释,线程 A 长期无奈失去无效执行,处于饥饿状态。极其状况下,可能被饿死。
  • 活锁:绝对于死锁和饥饿,活锁是一种绝对好的状态。大家在生活中必定遇到过这样一种状况,你在楼梯拐角遇到一个共事,空间无限所以二人茬住了。你向左挪动,你的共事也向左挪动;你向右挪动,你的共事也向右挪动;所以你们两个人都无奈向前挪动,这就是一个典型的活锁 。因为人是高智慧的动物,又都懂得礼让,所以对于人来说活锁的问题很好解决,只有其中一个人原地不动,另一个人动一下就过来了。然而多线程面对活锁的时候就没有那么智能了,有可能呈现一直地开释资源(向左移)、占用资源(向右移) 的循环中,即便最终活锁被解开,其资源开销及工夫老本都是很大的。

欢送关注我的博客,更多精品常识合集

本文转载注明出处(必须带连贯,不能只转文字):字母哥博客 – zimug.com

感觉对您有帮忙的话,帮我点赞、分享!您的反对是我不竭的创作能源!。另外,笔者最近一段时间输入了如下的精品内容,期待您的关注。

  • 《kafka 修炼之道》
  • 《手摸手教你学 Spring Boot2.0》
  • 《Spring Security-JWT-OAuth2 一本通》
  • 《实战前后端拆散 RBAC 权限管理系统》
  • 《实战 SpringCloud 微服务从青铜到王者》
正文完
 0