0

同期に関する質問:

Set s = Collections.synchronizedSet(new HashSet());
private Object monitor_ = new Object();

//Set has element added in another routine...

//Called by some thread1, thread2, ...
TimerTask run(){ //method which executes every 1 min
  synchronized(monitor_) {
  s.isEmpty()
  // ...
  // waits for 30 seconds
  // JNI call
  // ...
 }
}

//Called by cleanup thread
removecall()
{
 synchronized( monitor_ ) {
   s.remove( something );
 }
}

Problem: TimerTask run メソッドが実行されている間、クリーンアップ スレッドは待機する必要があります。待たずにこの状況を処理する効率的な方法。例: リエントラント ロック

4

4 に答える 4

1

並行 Set が解決策になる可能性があります: CopyOnWriteArraySetまたは Collections.newSetFromMap( ConcurrentHashMap ) ですが、あなたの問題について私が知っていることを考えると、言うのは難しいです。

于 2012-06-22T12:06:04.177 に答える
0

両方の作業を同時に実行したい場合は、これを試してください。use 2 different objects in the synchronized block.

例えば:

Set s = Collections.synchronizedSet(new HashSet());

private Object monitor_1 = new Object();
private Object monitor_2 = new Object();

TimerTask run(){ //method which executes every 1 min
  synchronized(monitor_1) {
  s.isEmpty()

 }
}


removecall()
{
 synchronized( monitor_2) {
   s.remove( pcg );
 }

}
于 2012-06-22T12:47:23.057 に答える
0

ConcurrentLinkedQueueを「メッセンジャー」として使用すると、スレッド間で簡単に通信できます。次に、そのキュー内に何かを単純に入れることができますpublic static String DONE = "DONE"

これで、時々キューをポーリングするだけで済みます。キューが空でない場合は、任意のアクションを実行できます。これにより、プログラム フローが実際に非同期になり、拡張が非常に簡単になります。

于 2012-06-22T12:03:09.960 に答える
0

いくつかのことが思い浮かびます:

  • を呼び出すmonitor_.wait()と、スレッドは のロックを解放するmonitor_ため、同期された他のスレッドmonitor_が実行できるようになります。
  • もう 1 つのオプションは、無期限に待機し、ハッシュセットを変更するメソッドをオーバーライドして を呼び出すことです。これにより、メソッドが wait() から抜け出しmonitor_.notify()ます。run()これは、定期的なチェックよりもはるかにクリーンであり、変更が (平均で) 30 秒/2 ごとではなくすぐに検出されるため、システム全体の反応が速くなります。
于 2012-06-22T12:05:27.790 に答える