《并发编程专栏》,本文计息介绍一些相对深入一些的概念
一、临界区
这里的共享资源实际就是临界区的概念,临界区的资源在同一时间只能被一个线程(住户使用,所以一旦临界资源被占用,其他的线程(住户能做的就只有等待。
二、阻塞和非阻塞
了解了临界区的概念之后,阻塞概念就好理解了。一个线程先占用了临界区的资源,此时如果其他的线程想使用临界区资源就必须等待。这种占用临界区资源,阻塞其他线程继续执行的情况就是线程阻塞(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长期无法得到有效执行,处于饥饿状态。极端情况下,可能被饿死。
欢迎关注我的博客,更多精品知识合集
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力!。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。