47.
如果n个线程刚好可以分成2组, 第一组的行为i与lemma5.1的行为一样,第二组的行为与Lemma5.1的行为一样,则它们有一个2值初始状态。48.
49.
因为critical state必须是bivalent,所以2个后续只能 1-valent + 0-valent或者 x + bivalent。因为if any thread moves ,the protocol has a critical state,所以后续只能是univalent。所以只能是 1-valent + 0-valent。
50.
将 n个线程分成2组,每组的线程都完全同步并行,并且行为与2线程protocol的2个线程完全一样;则如果2个线程不能decide,n个线程也不能。51.
将k值与2值做映射,比如
if(k >= MAXK / 2)
{
k = 1;
}else
{
k = 0;
}
则n线程decide on k后再映射成2值。
52.
以58题答案为例
53.
consensus >= 2:
package jokes;
import java.util.Stack;
public class StackProtocol
{
private int[] proposes;
static ThreadLocal<Integer> ThreadId = new ThreadLocal<Integer>()
{
protected Integer initialValue()
{
return new Integer(0);
}
};
static final int WIN = 1;
static final int LOSE = 2;
private Stack<Integer> stack;
public StackProtocol()
{
proposes = new int[2];
stack = new Stack<Integer>();
stack.push(LOSE);
stack.push(WIN);
}
private void propose(int v)
{
proposes[ThreadId.get()] = v;
}
public int decide(int v)
{
propose(v);
if(stack.pop() == WIN)
{
return proposes[ThreadId.get()];
}else
{
return proposes[1 - ThreadId.get()];
}
}
}
consensus < 3:
Both A & B pop(): 不论A先或B先,2个pop()结束后,C solo的时候无法区分谁是winner
A push & B pop: A.push() --> B.pop() 与AB都没有动作不能区分; B.pop() --> A.push() 与只有A.push()无法区分。
A push & B push: 2种顺序Stack状态一样,无法区分。
54.
如下所示:
package jokes;
import java.util.concurrent.LinkedTransferQueue;
public class QueuePeekConsensus
{
private LinkedTransferQueue<Integer> q;
public QueuePeekConsensus(int n)
{
q = new LinkedTransferQueue<Integer>();
}
private void propose(int v)
{
q.put(v);
}
public int decide(int v)
{
propose(v);
return q.peek();
}
}
55.
不能。因为R(AB)只能被A和B访问,即只有2个现成参与。可以将CompareAndSet用getAndIncrement实现。则这个协议是由Common2寄存器和原子寄存器构成的,一致数为2。
一个反例:
A.CAS(RAB) --> B.CAS(RAB) --> B.CAS(RBC) --> C.CAS(RBC) --> C.CAS(RAB) --> A.CAS(RBC)
==> A-->B-->C-->A
56.
如下所示:
package jokes;
import java.util.concurrent.atomic.*;
public class CAS32Protocol
{
public final int THREADNUM = 3;
public final int THREADA = 0;
public final int THREADB = 1;
public final int THREADC = 2;
public final int INITIAL = -1;
private AtomicInteger[] casObjs;
private int[] proposes;
public CAS32Protocol()
{
proposes = new int[THREADNUM];
casObjs = new AtomicInteger[THREADNUM]; //ab, bc, ac
for(int i = 0; i < THREADNUM; i ++)
{
casObjs[i] = new AtomicInteger(INITIAL);
}
}
private synchr