1

Java でブロックしないように、オブジェクトがロックされている (同期されている)かどうかをどのように判断しますか?
しかし、解決策がわからないという問題があります。
私の Web アプリケーションでは、データ コンテナーを更新するプロセスがあり、時間がかかることがあります。リフレッシュは時間間隔で強制的に行われます。もちろん、1 つの更新がまだコンテナー上で動作している場合、別の更新はできません (コンテナー内のデータが破損しないようにするため)。
バックグラウンド スレッドを使用してコンテナーを更新したい。複数のバックグラウンド ワーカーが複数のコンテナーで同時に作業できます (ユーザー セッションごとに異なるワーカーがあり、ユーザー セッションごとにコンテナー内のデータが異なる場合があります)。
もちろんできますsynchronize(myContainer)ワーカーで、他のワーカーが現在この特定のコンテナーを更新していないことを強制します。しかし、コンテナで作業しているワーカーがいるかどうかを確認し、作業している場合は終了したいと思います。また、コンテナのコー​​ドを変更したくないので、コンテナクラス内に ReentrantLock を追加してロックしたくありません。
そのため、ワーカーにはインスタンスがMyContainerあり、他のワーカーが現在このコンテナー インスタンスを更新しているかどうかを判断したいと考えています。

それを達成する方法はありますか?

4

3 に答える 3

2

を使用してAtomicBoolean、このコードをMyContainerクラスに入れます。

AtomicBoolean isRefreshing = new AtomicBoolean(false);

void refresh() {
  if ( isRefreshing.compareAndSet( false, true)) {
    try {
      // refresh
    } finally {
      isRefreshing.set( false);
    }
  }
}

MyContainer に触れられない場合は、AtomicBoolean と MyContainer インスタンスを保持する RefreshWrapper を作成してください。

于 2013-06-24T14:20:00.263 に答える
1

コンテナをConcurrentLinkedQueueに入れ、ワーカースレッドpollをキューに入れます。

Container container;
while((container = queue.poll()) != null) {
    container.refresh();
}

次に、コンテナーが更新時に追跡されているかどうかに応じて、2 つのオプションがあります。

  • そうである場合はoffer、更新されたらすぐに、更新されたコンテナーをキューに戻すことができます。ガードを使用if(container.refreshTime < X)して、同じ時間間隔でコンテナーを 2 回更新しないようにすることができます。
  • そうでない場合は、次のいずれかを実行できます
    • 2 つを使用ConcurrentLinkedQueuesし、それらを交互に使用します: pollonqueue1offer更新されたコンテナー on queue2、および whenqueue1が空の次の時間間隔までスリープし、その時点pollで onqueue2offer更新されたコンテナー on queue1
    • または、コンテナーの配列をメイン スレッドに保持しoffer、ワーカー スレッドがすべてのコンテナーの更新を完了してスリープ状態になったら、コンテナーをキューに戻します。
于 2013-06-24T13:23:40.657 に答える