晚飯后,老王和媳婦在路上走侄非。
“聽(tīng)說(shuō)今天診所又有人打架了蕉汪?”老王媳婦突然說(shuō)。
“兩對(duì)年輕的夫婦逞怨,都是來(lái)給孩子看病的者疤,說(shuō)實(shí)在的,我也的確沒(méi)有看清楚他們到底誰(shuí)先來(lái)的叠赦,但他們都說(shuō)自己先來(lái)的驹马。”老王無(wú)奈的說(shuō)除秀。
“要是我也能看病就好了糯累,這樣他們就不用打架了〔岵龋”媳婦安慰老王寇蚊。
“咱兩都看病,誰(shuí)抓藥呢棍好!”老王心中的無(wú)奈更重了仗岸。
老王和媳婦的診所在可樂(lè)鎮(zhèn)開(kāi)了二十年了,因?yàn)樾Ч媒梵希瑑r(jià)格也公道扒怖,所以每天慕名前來(lái)看病的人不少。
“你看這樣行不行业稼,”兩人沉默了一會(huì)兒盗痒,老王突然說(shuō),“我們?cè)陂T(mén)上掛一個(gè)牌子低散,誰(shuí)先拿到這個(gè)牌子俯邓,就先給誰(shuí)看∪酆牛”
“但是搶牌子會(huì)不會(huì)打架稽鞭?”媳婦問(wèn)。
“不會(huì)引镊,牌子上會(huì)隨機(jī)附上一道關(guān)于健康知識(shí)的問(wèn)題朦蕴,誰(shuí)先答上來(lái)誰(shuí)就先拿到牌子篮条。”老王早有準(zhǔn)備吩抓。
“會(huì)不會(huì)同時(shí)答上來(lái)涉茧?”
“會(huì)不會(huì),誰(shuí)先答上來(lái)的疹娶,還不是由咱們說(shuō)了算伴栓。”老王有點(diǎn)得意雨饺。
“那沒(méi)有搶到牌子的怎么辦钳垮?”
“我準(zhǔn)備重新改造下現(xiàn)在的候診區(qū),給每個(gè)座位編上號(hào)沛膳,然后按照從小到大的順序排列,沒(méi)有搶到牌子的就到最小且空閑的號(hào)上等待汛聚。新進(jìn)來(lái)的人可以直接排隊(duì)锹安,也可以不排隊(duì),直接去搶牌子倚舀√究蓿”
“那他肯定搶不到......”媳婦機(jī)智地說(shuō)。
“也不一定痕貌,假如當(dāng)他去搶牌子的時(shí)候风罩,看完病的人正好出來(lái)把牌子復(fù)位到了門(mén)上......”
“也對(duì),這個(gè)時(shí)候就能搶到牌子了舵稠〕”
“也不一定,因?yàn)榭赐瓴〉娜诉€會(huì)喚醒等待隊(duì)列最前面的人哺徊∈易粒”老王給剛才候診的隊(duì)列起了個(gè)名字叫等待隊(duì)列。
“對(duì)落追,這個(gè)時(shí)候就是兩人回答問(wèn)題競(jìng)爭(zhēng)了盈滴。”媳婦恍然大悟轿钠。
代碼實(shí)現(xiàn)故事
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
} // 公平鎖:進(jìn)來(lái)后巢钓,直接去排隊(duì) 非公平鎖:進(jìn)來(lái)后,先搶一次牌子疗垛,再去排隊(duì)
final void lock() {
if (compareAndSetState(0, 1)){
setExclusiveOwnerThread(Thread.currentThread());
} // 先搶一次牌子
else{
acquire(1);
}
}
public final void acquire(int arg) {
if (!tryAcquire(arg) // 沒(méi)有搶到牌子
&&acquireQueued(addWaiter(Node.EXCLUSIVE), arg)){ // 排隊(duì)
selfInterrupt();
}
}
/**
排隊(duì)邏輯:
1症汹、0號(hào)椅子不坐人,隊(duì)列的頭和尾都指向0號(hào)椅子
2贷腕、第一個(gè)人坐1號(hào)椅子烈菌,隊(duì)列的頭指向0號(hào)椅子阵幸,隊(duì)列的尾指向1號(hào)椅子
3、第二個(gè)人坐2號(hào)椅子芽世,隊(duì)列的頭指向0號(hào)椅子挚赊,隊(duì)列的尾指向2號(hào)椅子
4、以此類(lèi)推
**/
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
private Node enq(final Node node) {
for (; ; ) {
Node t = tail;
if (t == null) {
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
“如果搶到牌子的人進(jìn)來(lái)后济瓢,卻發(fā)現(xiàn)自己沒(méi)有帶醫(yī)避睿卡,怎么辦旺矾?”媳婦突然問(wèn)蔑鹦。
“候診室內(nèi),我開(kāi)辟了幾塊空間箕宙,每塊空間的椅子也編上號(hào)嚎朽,然后按照從小到大的順序排列,沒(méi)有帶醫(yī)奔砼粒卡的在一塊空間排隊(duì)哟忍,沒(méi)有帶身份證的在一塊空間排隊(duì),總之一類(lèi)人一個(gè)隊(duì)伍陷寝」埽”老王說(shuō)。
“那我們現(xiàn)在的地方豈不是不夠用了凤跑”玻”媳婦擔(dān)憂(yōu)的說(shuō)。
“按照我的想法仔引,條件隊(duì)列沒(méi)有數(shù)量限制扔仓,”老王給剛才的空間起了個(gè)名字,“不過(guò)一般情況也不會(huì)有那么多人去排隊(duì)咖耘,所以我們先緊著目前的地方用当辐,不夠用了再說(shuō)±鹂矗”老王自行的說(shuō)缘揪。
“那他們就一直在那里排隊(duì),醫(yī)币骞穑卡也不會(huì)自己飛過(guò)來(lái)找他們罢殷荨!”媳婦又提出一個(gè)擔(dān)憂(yōu)慷吊。
“那是自然的袖裕,他們得通知家里人,把醫(yī)备绕浚卡送過(guò)來(lái)急鳄,然后喚醒他到等待隊(duì)列中繼續(xù)去排隊(duì)谤民。”老王解釋到疾宏。