有一个ExecutorService
有3个主题,每个主题都会将Pair<String,Integer>
个对象添加到TreeSet<Pair<String,Integer>>
。 addToSet()方法声明为synchronized
,一切正常。但是我必须实现一个执行计划任务的新线程,该计划任务必须访问此Set并打印所有值。问题是有时预定的线程崩溃(其他线程工作正常)。我认为它崩溃了,因为在打印机的for循环(预定线程)期间,其他3个线程正在修改Set。
答案 0 :(得分: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
}
}
答案 1 :(得分:0)
实现此目标的最安全方法是在同步上下文中创建集合的防御副本,并将其用于其他进程。
简单粗略地说:
public void run() {
TreeSet<...> localSet;
synchronized (commonSet ) {
localSet = new TreeSet(commonSet);
}
doStuff(localSet);
...
}
请注意,这不能解决对集合中对象的并发访问(如果这些是可变的。)