2

Java での同期に関して、比較的単純な (おそらくばかげた) 質問があります。

コード全体でさまざまなオブジェクトのロックを取得する同期ブロックがあります。いくつかのシナリオでは、コード内の他のすべての同期ステートメントを包含するグローバル ロックを取得したいと考えています。

現在の同期コードをすべて書き直さずに Java でこれを行うための素晴らしい方法はありますか?

例えば、

スレッド t1

synchronized (o1)
{
    synchronized (o2)
    {
        // ...
    }
}

スレッド t2

synchronized (global_lock)
{
    // ...
}

スレッド t2 が同期ブロック内にある場合、スレッド t1 は o1 と o2 のロックを取得できません。

どうもありがとう

4

3 に答える 3

11
  1. 不可能です;
  2. それは本当に悪い考えです(ごめんなさい)。

ロックがどこにあるかに関係なく、すべてのロックに対して事前に決定されたロック順序が強制されるため、デッドロックが発生しやすくなります。

通常、2 つのロックを取得する必要がある場合は、常に事前に決められた順序にすることをお勧めします。

synchronized(LOCK1) {
  synchronized(LOCK2) {

  }
}

しかし、グローバル ロックには、すべてのロックに対して何らかのプロトコル (グローバルな取得順序) が必要です。そして、それはまったく不可能かもしれません。ほとんどのロックは、特定の自己完結型のクリティカル セクションを保護します。彼らは、誰かがそれらを「ヤンク」して取得することを認識していないため、この状況を処理するように書かれていません。

だからそれは不可能であり、そうではないことを喜ぶべきです。簡単な方法のように思えますが、それは多くの苦痛をもたらすでしょう。

于 2009-06-07T11:18:19.120 に答える
1

あなたが提案していることの恐ろしさはさておき、アスペクト指向プログラミング (AOP) を使用して、実行時にコードに追加の同期/ロックを「織り込む」ことを検討することをお勧めします。ソースを書かずにこれを行うことができるはずです。

AspectJ や Spring AOP など、多くの AOP オプションがあり、環境によっては適切な場合があります。

于 2009-06-07T14:20:47.643 に答える
-1

それを行う唯一の実行可能な方法は、実際にすべてのコードを解析/変更/保存 (自動的に) することです。私は最近、プロジェクトのためにこのようなことをしましたが、かなりうまくいきました。興味があれば、もっと話せます。

于 2009-06-07T11:21:13.980 に答える