Java哈希集同步查询

Java哈希集同步查询,java,synchronization,hashset,Java,Synchronization,Hashset,同步问题: 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 synchroniz

同步问题:

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 );
 }
}
问题:
当TimerTask运行方法正在执行时,清理线程必须等待。任何有效的方法
不必等待就可以处理这种情况。e、 g重入锁

如果使用a作为“信使”,则可以轻松地在线程之间通信。然后,您可以简单地将一些内容放入该队列中,例如一个表示线程是否已完成工作的字符串,例如
publicstaticstringdone=“done”


现在,您只需每隔一段时间轮询队列一次:如果队列不为空,则可以执行任何操作。这使得您的程序流非常异步,并且非常容易扩展。

我想到了两件事:

  • 当您调用
    monitor\uuu.wait()
    时,线程会释放
    monitor\uu
    上的锁,以便在
    monitor\uu
    上同步的其他线程可以执行
  • 另一个选项是,您只需无限等待,并重写修改哈希集的方法,以便它们调用
    monitor.notify()
    ,这将使您的
    run()
    方法脱离等待()。这将比定期检查干净得多,并使整个系统反应更快,因为变化将立即检测到,而不是每30秒/2(平均)检测一次

并发集可能是解决方案:或Collections.newSetFromMap(),但鉴于我对您的问题的了解,很难说。

试试这个,如果您想同时完成这两项工作,
在同步块中使用两个不同的对象。

例如:


你能告诉我们
TimerTask.run()
的内容吗?你的问题不是很清楚。要么需要同步timertask和cleanup线程中的2个操作,要么不同步。如果您的目的只是为了保证对集合的线程安全访问,则不需要在使用synchronizedSet的基础上进行额外的同步。@assylias yes希望对集合进行安全访问,但根据java文档,用户必须在对返回的集合进行迭代时手动对其进行同步。@orzechowskid run()调用JNI方法。有点奇怪,但仅供参考的计时器/计时器任务是半弃用的。改用遗嘱执行人。有关详细信息,请参阅此线程:
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 );
 }

}