Art of Multiprocessor Programming 答案 ch10

来源:互联网 发布:穷文富武 知乎 编辑:程序博客网 时间:2024/04/30 12:10

119.

  private enum NodeType {ITEM, RESERVATION, SENTINEL};public class SynchronousDualQueue<T> {  AtomicReference<Node> head;  AtomicReference<Node> tail;    private final Node NullNode = new Node(null, NodeType.SENTINEL);  /* Replace all null with NullNode */}

120.

package p120;public class TwoThreadLockFreeQueue<T> {int head = 0, tail = 0;T[] items;@SuppressWarnings("unchecked")public TwoThreadLockFreeQueue(int capacity){head = tail = 0;items = (T[]) new Object[capacity];}public void enq(T x){//rmbwhile(tail - head == items.length) {//rmb}items[tail % items.length] = x;tail ++;//wmb}public Object deq(){//rmbwhile(tail == head) {//rmb }Object x = items[head % items.length];head ++;//wmbreturn x;}}

121.

122. 必须。head.next != null --> deq 必须是原子的,否则可能有这样的case:queue中只有一个元素,2个线程deq,2个现成都得到head.next != null,然后2个现成分别在拿到锁之后deq,错误。

123.

使用SynchronousDualQueue, 在enq或deq消除(而不是加入list)的时候排除不符合要求的case。是分散的,低征用的,随机的。

124.

1. 应该以38行成功为线性化点,否则,

假设queue的状况是  head(A)-->B-->C-->sentinel

2个线程deq的执行顺序是  ThreadA.CAS --> ThreadB.CAS --> ThreadB.return --> ThreadA.return

以return为线性化点,返回结果应该是ThreadB得到A,ThreadA得到B; 但是算法的结果是 ThreadA得到A,ThreadB得到B。

2. enq的线性化点位16行成功。如果以tail更新为可线性化点,假设一个线程16行执行部成功,但是21行更新tail成功,则这个方法在没有实际enq的情况下使是方法的执行状态可见,这没有意义。

125.

1. enq是无等待的,因为每个调用能够在有限步完成。deq不是无锁的,假设只有一个deq线程,没有enq,这个线程运行无限步也不能完成一个调用。

2. 大概是这样:

deq()的可线性化点在13行成功地时刻。

对于enq和deq的操作,enq的可线性化点在第7行执行结束。

对于enq和enq的操作,enq的可线性化点在它们enq的值被deq成功的时刻,即第13行操作成功的时刻。

Reference: Reading the Linearizability paper of Herlihy and Wing

0 0