Java 将元素添加到synchronizedList(如果不存在)
我让多线程访问这个synchronizedList:downloadingFiles,并且我只想在synchronizedList中不存在这个元素的情况下将元素添加到这个synchronizedList中,是否需要进行以下双重检查和同步?还有更好的办法吗Java 将元素添加到synchronizedList(如果不存在),java,multithreading,Java,Multithreading,我让多线程访问这个synchronizedList:downloadingFiles,并且我只想在synchronizedList中不存在这个元素的情况下将元素添加到这个synchronizedList中,是否需要进行以下双重检查和同步?还有更好的办法吗 if (!downloadingFiles.contains(file.getAbsolutePath())) { synchronized(this) { if (!downloadin
if (!downloadingFiles.contains(file.getAbsolutePath())) {
synchronized(this) {
if (!downloadingFiles.contains(file.getAbsolutePath())) {
downloadingFiles.add(file.getAbsolutePath());
}
}
}
是的,那会有用的。但是,通过双重检查锁定获得的性能增益可能不值得额外检查
换句话说,考虑删除第一个if语句,除非你真的希望这个方法经常被多个线程调用。 另外,如果您实际使用的是
Collections.synchronizedList()
,则需要对列表本身执行synchronized(…)
,因为这是内部使用的
synchronized(downloadingFiles) {
if (!downloadingFiles.contains(file.getAbsolutePath())) {
downloadingFiles.add(file.getAbsolutePath());
}
}
您是否考虑过使用同步
集
?然后,您可以让Set
处理重复项的问题?如果列表已经同步,那么在同步块之外没有进行第一次检查的必要。如果还没有同步,那么第一个检查可能不是线程安全的。要补充@MadProgrammer所说的,如果插入顺序很重要,您可以使用同步的LinkedHashSet。@jtahlborn想象两个线程,都是检查列表#包含的,第一个线程通过,但在它可以完成项目之前,第二个线程也通过(不再锁定),您现在有机会让两个线程将同一元素添加到列表中
@MadProgrammer-您误读了我的评论吗?我没有说要删除包含检查,我说的是在同步块之外删除检查(假设列表已经同步),同时维护同步块。。。