7

同じオブジェクトで同期したい2つのスレッドがあります。特定の条件が満たされた場合、TheadはスレッドAを中断できる必要があります。Bこれは、2つのスレッドが実行する/実行する必要があることの擬似コードです。

A:

public void run()
{
    while(true)
    {
        //Do stuff
        synchronized(shared)
        {
            //Do more stuff
            if(condition)
            {
                B.interrupt();
            }
        }
    }
}

B:

public void run()
{
    while(true)
    {
        try
        {
            //Do stuff
            synchronized(shared)
            {
            //Do more stuff
            }
        }
        catch(InterruptedException e)
        {
            continue;
        }
    }
}

これが私が解決できない状況です:

  • スレッドAは共有リソースを取得し、いくつかのことを行います。
  • その間、スレッドBは同期ブロックに到達しA、共有リソースを解放するのを待ちます。
  • スレッドAは、作業中に、スレッドBが共有リソースを持つべきではないことに気づき、スレッドを中断しようとしBます。しかし、スレッドはすでにスローされる可能性Bのあるポイントを超えています。InterruptedException

私の質問は、スレッドが何かを待っている間にスレッドを中断する方法はありますsynchronizedか?

4

3 に答える 3

6

この種のことについては、クラスを使用する必要がありますjava.util.concurrent.locks-それらは、割り込み可能なロックを含む、はるかに多くの機能を備えています。

編集:これらのクラスを使用できない場合は、jkffの答えを見てください。要件はwait()/メカニズムで満たすことができますnotify()が、微妙なバグを簡単に導入できます。

于 2010-02-21T14:01:49.640 に答える
3

実際、ロックを使用するかObject.wait()Object.notify()およびObject.notifyAll()メソッドを使用して自分のものを実装する必要があります(ロックは実際にはそれらを使用して実装されます)。いわゆる「スプリアスウェイクアップ」を処理することを忘れないでください(誰もまたはをwait()呼び出さなくても戻る可能性があるため、待機している条件が満たされていることを確認するループで常に呼び出す必要があります)。notify()notifyAll()

于 2010-02-21T14:27:49.397 に答える
1

いいえ。ただしReentrantLock.lockInterruptibly()、プリミティブmonitorenter命令と同様に動作し、中断することができます。

于 2010-02-21T14:56:00.080 に答える