我有一个字符串(tagList)列表,需要在多个线程之间共享以供读取,因此我创建了它的不可修改版本并将其传递给线程,我不确定它是否是线程安全的,因为线程只读取该列表,所以我猜应该可以吧?
另外,当我将不可修改的列表传递给线程时,它是传递单个副本并由线程共享,还是创建多个副本并将一个副本传递给每个线程?
这是我的代码:
final List<String> tList = Collections.unmodifiableList(tagList);
List<Future<Void>> calls = new ArrayList<Future<Void>>();
FileStatus[] fsta = _fileSystem.listStatus(p);
for (FileStatus sta : fsta) {
final Path path = new Path(sta.getPath(), "data.txt");
if (!_fileSystem.exists(path)) {
continue;
}
else {
calls.add(_exec.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
filterData(path, tList);
return null;
}
}));
}
}
这完全取决于底层列表在读取操作上是否是线程安全的。不可修改的列表只传递所有读取调用,例如size ()
, get (int)
等到底层列表,无需额外同步。
例如,想象一下 List 的实现,它缓存哈希代码而不是每次需要时计算它。对于这样的实施,hashCode ()
方法实际上不是只读的,因为它可能会修改内部缓存的哈希码值。
另一个例子是 LinkedList 的一种风格,它缓存对最后访问的条目及其索引的引用,因此进一步尝试访问附近的元素将执行得更快。对于这样的实现,方法get (int)
将不是只读的,因为它更新缓存的引用和索引,因此可能不是线程安全的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)