0
public class cyclicBarrier {
    private static int n;
    private static int count;
    private static semaphore mutex;
    private static semaphore turnstile;
    private static semaphore turnstile2;

    public cyclicBarrier(int n){
        this.n = n;
        this.count = 0;
        this.mutex = new semaphore(1);
        this.turnstile = new semaphore(0);
        this.turnstile2 = new semaphore(0);
    }

    public synchronized void down() throws InterruptedException{
        this.phase1();
        this.phase2();
    }

    private synchronized void phase1() throws InterruptedException {
        this.mutex.down();
        this.count++;
        if (this.count == this.n){
            for (int i=0; i< this.n; i++){
                          this.turnstile.signal();
                    }
        }
        this.mutex.signal();
        this.turnstile.down();
    }

    private synchronized void phase2() throws InterruptedException {
        this.mutex.down();
        this.count--;
        if (this.count == 0){
            for (int i=0; i< this.n; i++){
                          this.turnstile2.signal();
                    }
        }
        this.mutex.signal();
        this.turnstile2.down();
    }
}

&&念のため、クラスセマフォはここにあります

public class semaphore{
    private int counter;

    public semaphore(int number){
        if (number > 0) {
            this.counter = number;
        }
    }

    public synchronized void signal(){
        this.counter++;
        notifyAll();
    }

    public synchronized void down() throws InterruptedException{
        while (this.counter <= 0){
            wait();
        }
        this.counter--;
    }
}

これは、スレッドを使用してCyclicbarriersを実装するために作成したコードです。本から疑似コードとデッドロックに関するメモを取りましたので、「バグがあるかもしれませんが」大丈夫だと思います。最初のフェーズは「スレッドの到着」であり、2 番目のフェーズは「クリティカル領域でスレッドを一緒に実行する」ためのものです。私の質問は次のとおりです...特定のタイプのスレッドを考慮するためにコードを変更する方法は? たとえば、水素スレッドと酸素スレッドがあり、バリアに水素原子が 2 つと酸素原子が 1 つあるたびに bond() を実行する必要があります。前もって感謝します。

4

2 に答える 2

1

答えではなく、ヒントを教えます。完全な回答が必要な場合はお知らせください。

まず、あなたの他の質問に対する私の答えに従ってコードを修正してください— 私がその欠陥について正しければ、それは :)

次に、m 個のスレッドと、m >= 2nのバリア(n)があり、各スレッドが実行しているとします。

while True:
    noncritical()
    barrier.enter() # e.g. phase1()
    critical()
    barrier.leave() # e.g. phase2()

私が提案したようにenter()leave()を実装すると、クリティカル セクションに2nスレッドが存在する可能性があります。この問題を解決するために、次の構成を考え出しました。

class N_At_A_Time_Barrier(n):
    fields:
        occupied = Semaphore(n)
        barrier = Barrier(n)
    method enter():
        occupied.down()
        barrier.down()
    method leave():
        occupied.up()

The Little book of Semaphoresの用語では、占有されているのは Multiplex です。ヒント: H2O 問題の解決策は、これと非常によく似ています。私のソリューションはBarrier(1+2)と...何か他のものを使用します:)

(脚注: N_At_A_Time_Barrierを実装するより効率的な方法があります。nスレッドの各グループは、最初に到着したスレッドによって設定された独自の共有状態を持ちますが、それははるかに複雑であり、H2O とは関係ないと思います問題はきれいに。)

于 2014-11-11T11:55:22.210 に答える
0

Cyclicbarriers を自分で実装する必要がありますか? (宿題)またはJDKの実装を使用できますか? http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html

おそらく、await() メソッドを拡張して、Atom の種類を含め、バリアで待機しているアトムを通知するメソッドを追加できます。H20 と言う条件が見つかった場合は、この中でコールバック メソッドを呼び出すことができます。 case bond(原子[]原子)

于 2013-03-31T01:59:12.103 に答える