Java 同时循环相同的列表安全吗?
我有一张单子Java 同时循环相同的列表安全吗?,java,multithreading,list,Java,Multithreading,List,我有一张单子 testList= new ArrayList<String>(); // gets initialized once at the very beginning init(). This list never changes. It's static and final. 我有很多线程同时使用这个方法并检查这个列表中是否有某个值。它似乎工作得很好。然而,我不确定这是否安全。我这样做对吗?它是线程安全的吗 只要在其他线程读取列表时没有线程修改列表,它就是线程安全的
testList= new ArrayList<String>(); // gets initialized once at the very beginning init(). This list never changes. It's static and final.
我有很多线程同时使用这个方法并检查这个列表中是否有某个值。它似乎工作得很好。然而,我不确定这是否安全。我这样做对吗?它是线程安全的吗 只要在其他线程读取列表时没有线程修改列表,它就是线程安全的 如果在列表上使用迭代器,则如果在迭代器下修改列表,它们将“快速失败”(如在throw
ConcurrentModificationException
)。其他访问方法(即get(n)
)不会引发异常,但可能会返回意外结果
这在Javadoc for
List
和ArrayList
中都有非常详细的介绍,您应该仔细研究。只要没有线程在其他线程阅读列表时修改列表,它就是线程安全的
如果在列表上使用迭代器,则如果在迭代器下修改列表,它们将“快速失败”(如在throwConcurrentModificationException
)。其他访问方法(即get(n)
)不会引发异常,但可能会返回意外结果
这在Javadoc for
列表和ArrayList
中都有详细介绍,您应该仔细研究。ArrayList
不是线程安全的对象。它现在可能适合您,但一般来说,在处理线程时,您应该确保使用的是线程安全对象,这些对象将按照您的预期处理线程
你可以用
testList=Collections.synchronizedList(新的ArrayList())代码>ArrayList
不是线程安全的对象。它现在可能适合您,但一般来说,在处理线程时,您应该确保使用的是线程安全对象,这些对象将按照您的预期处理线程
你可以用
testList=Collections.synchronizedList(新的ArrayList())代码>只要您能保证没有人在向列表中写入内容,它就安全了
请注意,即使列表是静态的和最终的,代码本身也不能保证列表不会被修改。我建议改用Collections.unmodifiableList()
,因为它保证不会在列表中添加或删除任何元素
顺便说一下,您可以将代码重写为:
public static boolean isInList(String var1) {
for (String s : testList) {
if (Objects.equals(s, var1)) {
return true;
}
}
return false;
}
或者只是
testList.contains(var1);
只要你能保证没有人在写名单,那就安全了
请注意,即使列表是静态的和最终的,代码本身也不能保证列表不会被修改。我建议改用Collections.unmodifiableList()
,因为它保证不会在列表中添加或删除任何元素
顺便说一下,您可以将代码重写为:
public static boolean isInList(String var1) {
for (String s : testList) {
if (Objects.equals(s, var1)) {
return true;
}
}
return false;
}
或者只是
testList.contains(var1);
是的,除非您正在添加/删除/更新列表中的元素。顺便说一下,使用另一个数据结构进行此类查询。例如,HashMap为什么不使用testList.contains(var1)
?是的,除非您正在添加/删除/更新列表中的元素。顺便说一下,使用另一个数据结构进行此类查询。例如,hashMap为什么不使用testList.contains(var1)
?而且,需要注意的是,列表必须首先安全地发布到每个线程。大多数处理线程引用的方法都很好;只是不要将其存储在非易失性静态字段中,让线程从中读取。同样值得注意的是,对于非线程安全列表(如ArrayList),您不能依赖ConcurrentModificationException的fail-fast行为,因为它所依赖的检查值很容易出现竞争条件。列表的迭代器方法(在for循环中调用)每次调用时都返回迭代器的新实例,因此,您可以在列表中同时循环多次而不会出现问题,而且,请注意,列表必须首先安全地发布到每个线程。大多数处理线程引用的方法都很好;只是不要将其存储在非易失性静态字段中,让线程从中读取。同样值得注意的是,对于非线程安全列表(如ArrayList),您不能依赖ConcurrentModificationException的fail-fast行为,因为它所依赖的检查值很容易出现竞争条件。列表的迭代器方法(在for循环中调用)每次调用时都返回迭代器的新实例,因此,您可以在列表中同时循环多次而不会出现问题