1

私はこのコードを持っています

public MultiThreadedSum(ArrayBuffer ArrayBufferInst)
{
    this.ArrayBufferInst = ArrayBufferInst;
    Sum = 0;
    Flag = false;
    StopFlag = false;
}

public synchronized void Sum2Elements()
{

    while(Flag)
    {
        try {wait();}
        catch (InterruptedException e){}
    }

    Flag = true;

    if (StopFlag)
    {
        notifyAll();
        return;
    }

    System.out.println("Removing and adding 2 elements.");

    Sum = ArrayBufferInst.Sum2Elements();

    notifyAll();
}

public synchronized void InsertElement()
{

    while(!Flag)
    {
        try {wait();}
        catch (InterruptedException e){}
    }

    Flag = false;

    if (StopFlag)
    {
        notifyAll();
        return;
    }

    System.out.println("Inserting the sum.");

    ArrayBufferInst.InsertElement(Sum);

    if (ArrayBufferInst.RetunrSize() == 1)
    {
        StopFlag = true;
    }

    System.out.println(ArrayBufferInst);

    notifyAll();
}

ご覧のとおり、最初に Flag を false に設定して、スレッドの 1 つが Sum2Elements メソッドに入り、それを true に変更して、全員を待たせるようにします。

同期されたコードでは、1 つのスレッドだけがそのことを実行できることを知っています。ここでは 2 つの同期されたメソッドがあります。2 つのスレッドが各 notifyall の後にこのメソッドを実行しようとしているということですか?

もしそうなら、一方のスレッドが Sum2Elements に入り、もう一方のスレッドが InsertElement に入る前にフラグを true に変更し、それによって while ループをスキップすることはできませんか?

ありがとう

4

3 に答える 3

0

ロックは、特定の同期メソッドではなく、クラスのオブジェクトで取得されます。どちらのメソッドもインスタンス メソッドです。したがって、スレッドの 1 つがオブジェクトの同期メソッドに入った場合、たとえば、実行中のスレッドがnotifyAll()メソッドを呼び出さなくなるまで、他のスレッドはそのオブジェクトの同期メソッドに入ることができません。その段階で、待機中のすべてのスレッドがアクティブになるために競合しますが、アクティブになるスレッドの選択はスレッド スケジューラに依存します。

2 つの異なるスレッドがこれらの同期メソッドに同時にアクセスする必要がある場合は、2 つのスレッドがクラスの 2 つの異なるオブジェクトで動作する必要があります。

于 2013-05-28T11:08:35.193 に答える
0

Only one thread can execute one of two method at a time because both are synchronized though order is undefined

lock私が言ったように、スレッドを実行してメソッドを解放しwait、他のスレッドを取得してlock他のメソッドを実行synchronizedし、両方のステートメントを可能にする場合を除き、一度に1つのスレッドでのみ1つのメソッドを実行できます。

于 2013-05-28T05:57:19.150 に答える