Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将元素添加到synchronizedList(如果不存在)_Java_Multithreading - Fatal编程技术网

Java 将元素添加到synchronizedList(如果不存在)

Java 将元素添加到synchronizedList(如果不存在),java,multithreading,Java,Multithreading,我让多线程访问这个synchronizedList:downloadingFiles,并且我只想在synchronizedList中不存在这个元素的情况下将元素添加到这个synchronizedList中,是否需要进行以下双重检查和同步?还有更好的办法吗 if (!downloadingFiles.contains(file.getAbsolutePath())) { synchronized(this) { if (!downloadin

我让多线程访问这个synchronizedList:downloadingFiles,并且我只想在synchronizedList中不存在这个元素的情况下将元素添加到这个synchronizedList中,是否需要进行以下双重检查和同步?还有更好的办法吗

        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-您误读了我的评论吗?我没有说要删除包含检查,我说的是在同步块之外删除检查(假设列表已经同步),同时维护同步块。。。