持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
注意点:
Condition就是读写锁的核心。写优先,读写平衡的策略,如果是写优先。
Condition应该如下:
Condition{
//如果当前有写任务等待或者当前是写任务,则阻塞
if(hasWriterWait || currentIsWriter){
return false;
}
//如果当前是读任务,则唤醒所有等待的任务
if(thisIsReader){
signalReader();
}
return true;
}
如果是读写平衡的公平策略,Condition应该如下:
Condition{
//如果下一个任务是写任务等待或者当前是写任务,则阻塞
if(nextWriterWait || currentIsWriter){
return false;
}
//如果当前是读任务,则唤醒所有等待的读任务
if(thisIsReader){
signalReader();
}
return true;
}
上述代码将hasWriterWait换成了nextWriterWait,作用是看看下一个等待的任务是什么,如果是写任务,则唤醒它(而不是看有没有写任务),如果是读任务,则唤醒一系列等待的读任务,知道碰到下一个写任务为止。简单而言,所有任务都在队列中排队,如果队列为r1-r2-r3-w1-r4-r5-w2,这里是r1任务先来,由于是读任务,因此r2、r3可以同时获得锁,也称为读锁,在w1排队中,因为读写不能兼容,当任务r1、r2、r3执行完成时,才会唤醒w1写任务,当写任务执行时,r4、r5、w2任务不能执行。注意,当w1释放写锁后,根据不同的策略会有不同的选择,如果是写优先,那么将w2移到w1的后面,唤醒w1;如果是公平策略,则唤醒r4和r5读任务。
可以看出读写锁适用的是读多写少的场景,几乎不会涉及到锁操作,如果是写多读少,使用读写锁并不会起到太大作用,就会退化成普通的互斥锁。
死锁
死锁是由于资源争用而导致的一种特殊现象,即任务彼此之间互相等待,导致谁也不能得到执行的一种现象。
死锁情况有以下:
- 有两个资源。
- 任务a获取到一个资源。
- 任务b获取到一个资源。
- 任务a需要任务b所获得的资源才能执行。
- 任务b需要任务a所获得的资源才能执行。
- 任务a不释放自己获得的资源。
- 任务b不释放自己获得的资源。
- 死锁。