美文网首页
大话ReentrantLock

大话ReentrantLock

作者: kele2018 | 来源:发表于2024-06-25 17:01 被阅读0次

晚饭后,老王和媳妇在路上走。
“听说今天诊所又有人打架了?”老王媳妇突然说。
“两对年轻的夫妇,都是来给孩子看病的,说实在的,我也的确没有看清楚他们到底谁先来的,但他们都说自己先来的。”老王无奈的说。
“要是我也能看病就好了,这样他们就不用打架了。”媳妇安慰老王。
“咱两都看病,谁抓药呢!”老王心中的无奈更重了。
老王和媳妇的诊所在可乐镇开了二十年了,因为效果好,价格也公道,所以每天慕名前来看病的人不少。
“你看这样行不行,”两人沉默了一会儿,老王突然说,“我们在门上挂一个牌子,谁先拿到这个牌子,就先给谁看。”
“但是抢牌子会不会打架?”媳妇问。
“不会,牌子上会随机附上一道关于健康知识的问题,谁先答上来谁就先拿到牌子。”老王早有准备。
“会不会同时答上来?”
“会不会,谁先答上来的,还不是由咱们说了算。”老王有点得意。
“那没有抢到牌子的怎么办?”
“我准备重新改造下现在的候诊区,给每个座位编上号,然后按照从小到大的顺序排列,没有抢到牌子的就到最小且空闲的号上等待。新进来的人可以直接排队,也可以不排队,直接去抢牌子。”
“那他肯定抢不到......”媳妇机智地说。
“也不一定,假如当他去抢牌子的时候,看完病的人正好出来把牌子复位到了门上......”
“也对,这个时候就能抢到牌子了。”
“也不一定,因为看完病的人还会唤醒等待队列最前面的人。”老王给刚才候诊的队列起了个名字叫等待队列。
“对,这个时候就是两人回答问题竞争了。”媳妇恍然大悟。

代码实现故事
public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
} // 公平锁:进来后,直接去排队   非公平锁:进来后,先抢一次牌子,再去排队
final void lock() {
    if (compareAndSetState(0, 1)){
        setExclusiveOwnerThread(Thread.currentThread());
    }  // 先抢一次牌子    
    else{
        acquire(1);
    }          
}
public final void acquire(int arg) {
    if (!tryAcquire(arg) // 没有抢到牌子
        &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg)){ // 排队
        selfInterrupt();
    }   
}
/**
排队逻辑:
1、0号椅子不坐人,队列的头和尾都指向0号椅子
2、第一个人坐1号椅子,队列的头指向0号椅子,队列的尾指向1号椅子
3、第二个人坐2号椅子,队列的头指向0号椅子,队列的尾指向2号椅子
4、以此类推
**/
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;
        }
      }
    }
 }

“如果抢到牌子的人进来后,却发现自己没有带医保卡,怎么办?”媳妇突然问。
“候诊室内,我开辟了几块空间,每块空间的椅子也编上号,然后按照从小到大的顺序排列,没有带医保卡的在一块空间排队,没有带身份证的在一块空间排队,总之一类人一个队伍。”老王说。
“那我们现在的地方岂不是不够用了。”媳妇担忧的说。
“按照我的想法,条件队列没有数量限制,”老王给刚才的空间起了个名字,“不过一般情况也不会有那么多人去排队,所以我们先紧着目前的地方用,不够用了再说。”老王自行的说。
“那他们就一直在那里排队,医保卡也不会自己飞过来找他们啊!”媳妇又提出一个担忧。
“那是自然的,他们得通知家里人,把医保卡送过来,然后唤醒他到等待队列中继续去排队。”老王解释到。

相关文章

网友评论

      本文标题:大话ReentrantLock

      本文链接:https://www.haomeiwen.com/subject/tncjcjtx.html