1

注: 回避策を探しているわけではありません。必要に応じて、他の方法を見つけることができると確信しています。何か基本的なことや変わったことが欠けているように感じて、何が欠けているのか知りたいのです。または、デバッガーを使用してより多くの情報を取得する方法があれば、それもいいでしょう。ありがとう!

同期の使用に問題があります。デッドロックが発生していますが、まったく不可能のようです。すべての同期呼び出しの前、各呼び出しのすぐ内側、および終了直前に print ステートメントを配置したので、誰がどの同期オブジェクトを保持しているかを確認できます。現在誰もオブジェクトのロックを保持していなくても、同期された呼び出しの 1 つに入らないことがわかりました。私が見逃している癖や違法なネスティング操作はありますか? これが私がやっていることの要点です。

そうそう、そして最も奇妙なことは、2 つの「busyFlagObject」同期を削除すると、正常に動作することです...

スレッド 1:

public void DrawFunction()
{
    synchronized(drawObject)
    {
        ...
        // Hangs here though nobody has a lock on this object
        synchronized(animationObject)
        {

        }
    }
}

スレッド 2:

public void AnotherFunction()
{
    synchronized(busyFlagObject)
    {
        // Calls a function that also uses this same Synchronized call
        synchronized(busyFlagObject)
        {
            // Calls another function that uses another Synchronized call
            // Hangs here waiting for the draw function to complete which it SHOULD 
            // be able to do no problem.
            synchronized(drawObject)
            {

            }

            // Never gets to this one assuming the Log statements don't 
            // buffer and aren't flushed but still shouldn't be a problem anyway.
            synchronized(animationObject)
            {

            }
        }
    }
}
4

1 に答える 1

2

アプリをデバッガーで実行するか、JDK ツールの「jstack」を使用します。これにより、ロックを待機しているスレッドとロックを保持しているスレッドが直接表示されるため、問題がどこにあるかを推測する必要はありません:-)

そうは言っても、あなたはブール値で同期すると言いました。クラスは 2 つのインスタンスのみを持つように意図されており、多くのこと (特にボックス化) により、ブール値のインスタンスが暗黙的に「共有」値に変更されることに注意してください。ロック オブジェクトが同じインスタンスではありませんか? new Object()監視オブジェクトとして使用することを検討してください。

これが発生する可能性があるのはこれだけではないことに注意してください。Java Concurrency in Practice に、特にstring interningを使用したこの問題に関する適切なエントリがありますが、現時点ではリンクを見つけることができません。自分の制御下にない型を意図していないものとして使用しないでください:-)

于 2013-01-09T03:09:19.140 に答える