3

コンセンサスに任意の数のスレッドが到達できることを示すために、peek() メソッドを使用するキューを使用するコンセンサス プロトコルを実装する必要があります。つまり、peek() メソッドを使用するキューには無限のコンセンサス数があります。

これは私のコードです

import java.util.LinkedList;
import java.util.Queue;
public class PeekConsensus extends ConsensusProtocol<Integer>   
{
    Queue<Integer> queue ;
    public PeekConsensus(int threadCount)   
    {
        super(threadCount); //threadCount is a command line argument from the main class specifying the number of threads to handle this process 
        queue = new LinkedList<Integer>() //FIFO queue
    }

    public Integer decide(Integer value)    
    {
        this.propose(value); // stores "value" in a vector named proposed, at index ThreadID.get()  
        int i = ThreadID.get() ;
        queue.add(i) 
        System.out.println("Thread " + i + " : " + i) ; // Required by specifications to print thread id and the value added when an item is enqueued 
        System.out.println("Thread " + i + " : " + queue.peek()) ; // Required by specifications to print thread id and the value of peek() when when peek() is called
        return proposed.elementAt(queue.peek()) ;

    }   
}

私の理解では、2 つのスレッドが異なる値を返す場合、peek() は異なるスレッド ID を返す必要があり、スレッド ID をプッシュする前に各スレッドが独自の値をプロポーザルに書き込むため、妥当性が保証されるため、これは機能するはずです。

私がどこで間違っているのかを理解し、コードを修正する方法を教えてくれる人はいますか

4

1 に答える 1

3

プロトコルは私には問題ないようです。しかし、実装方法について考えたことpeek()はありますか? peek()実際には a のpop()後に a が続くためpush()、このコードでは不適切なインターリーブが発生する可能性があります。このコンセンサス プロトコルは、peek()アトミックに実行できると仮定すると機能します。

どうすれば変更できますか?

コードを実行するために を追加synchronizedすることもできますpeek()が、スレッドがロックを保持して終了する可能性があるため、コンセンサス プロトコルの目的が無効になります。

を使ってみてくださいAtomicReference。これにより、アトミックに値を取得したり、設定したりすることができます。この場合、ポインタは になりますhead

ここで問題が発生します: AtomicReferenceJava でどのように実装されているか。残念ながら、これは を使用して実装されていCASます。これは、FIFO キューのみを使用するコンセンサス プロトコルの目的を再び無効にします。

最後に: 公式には、FIFO キューのコンセンサス番号は 2peek()です。アトミックに実行されると仮定すると、プロトコルは有効です。ただし、正しい実装には何らかのCASorが必要synchronizedです。

于 2017-08-22T07:57:17.860 に答える