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 运行方法正在执行时,清理线程必须等待。无需等待即可处理这种情况的任何有效方法。例如重入锁

4

4 回答 4

1

并发集可能是解决方案: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_可以执行
  • 另一种选择是您只是无限期地等待,并覆盖修改哈希集的方法,以便它们调用monitor_.notify(),这将使您的run()方法脱离等待()。这将比定期检查更干净,并使整个系统反应更快,因为将立即检测到更改,而不是每(平均)30 秒/2
于 2012-06-22T12:05:27.790 回答