0

このコードをJavaに変換しようとしており、スレッドを使用して実装しています

turn = 0 // shared control variable    
while (turn != i);
// CS
turn = (turn + 1) % n;  

私は正しいコードにたどり着くのに本当に苦労しましたが、失敗しましたこれは私のコードです

/*
 * Mutual exclusion using thread
 */
class gV{
int turn=0;
}

class newThread extends Thread{

    static int i;
    int n=10;
    newThread(gV obj){
    this.i=obj.turn;
    start();
    }

    public void run(){

    while(obj.turn!=i&&obj.turn<n);
    criticalSection(i);
    obj.turn=(obj.turn+1);
    i++;
    }

    public void criticalSection(int numOfProcess){
    System.out.println("Process " + numOfProcess + " done!!");
    }
}

class MutualExclusion{
    public static void main(String args[]){
    gV obj = new gV();
    new newThread(obj);
    }
}  

私のコードにはいくつかの間違いがあることを知っています。お手伝いありがとう!

4

1 に答える 1

4

を使用しAtomicIntegerます。

アトミックとは、他のスレッドが結果を確認する前に、その操作が完全に完了することを意味します。2つの同時操作がないことを意味します。たとえば、非アトミック整数があり、2つのスレッドが同時にインクリメントしようとした場合(たとえば、値が1の場合、両方とも1として読み取り、2に設定しようとします)、両方とも1回インクリメントしましたが、代わりに3になり、2になりました!AtomicIntegerを与えることでこの問題を解決します。これにより、増分が完了する前にIncrementAndGet他のスレッドがの値にアクセスできないことが保証されます。AtomicInteger

特に、次の方法を使用します。

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#get()

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet()

これによりインクリメントされることに気付くかもしれませんが、nを法としてはかかりません。その値を読み取るときはいつでも、nを法として取ることができます。そのように格納する必要はありません。

編集:ところで、このようなことをする:

while (turn != i);

これはビジーウェイトと呼ばれ、CPU使用率が100%になり、1秒間に数十万回変数をチェックすることを意味するため、お勧めできません。この種のシナリオでは、各スレッドをできるだけ頻繁にチェックするのではなく、スレッドを作成し、そのスレッドが実行を継続する番になったときに別のスレッドによって編集されるwait ようにします。notify

Javaを使用locksynchronizedて相互排除を実装すると、このプロパティも得られると思います。たとえば、何かをロックしようとしたり、同期ブロックに入ったりしても、すでに使用されている場合、スレッドはスリープ状態になり、スリープ状態になるとウェイクアップします。その番です。したがって、これも調べることができます。

于 2013-02-10T23:31:14.837 に答える