1

ExecutorService3 个线程,每个线程将Pair<String,Integer>对象添加到TreeSet<Pair<String,Integer>>. 声明了 addToSet() 方法synchronized,一切正常。但是我必须实现一个新线程来执行一个计划任务,该任务必须访问这个 Set 并打印所有值。问题是有时计划的线程会崩溃(其他线程工作正常)。我认为它崩溃是因为在打印机的 for 循环(计划线程)期间其他 3 个线程正在修改 Set。

4

2 回答 2

1

addToSet您需要在方法和打印所有值的方法之间互斥。一种方法:

Object setLock = new Object(); // Put this in a scope where all threads can access it

void addToSet( T element ){
    synchronized(setLock) {
       //add it
   }
}

void printAllValues(){
   synchronized(setLock) {
       //print the values
   }
}
于 2012-10-26T12:31:41.390 回答
0

实现这一点的最安全方法是在同步上下文中创建该集合的防御性副本,并将其用于其他进程。

粗略地说:

public void run() {
    TreeSet<...> localSet;
    synchronized (commonSet ) {
        localSet = new TreeSet(commonSet);
    }
    doStuff(localSet);
    ...
}

请注意,这并不能解决对集合中对象的并发访问(如果这些对象是可变的。)

于 2012-10-26T12:32:05.497 回答