同时循环同一个List是否安全?

时间:2017-02-20 16:53:10

标签: java multithreading list

我有一个清单

testList= new ArrayList<String>(); // gets initialized once at the very beginning init(). This list never changes. It's static and final. 

我有一个静态方法,用于检查输入值是否在此List中:

public static boolean isInList (String var1)
            throws InterruptedException  {

        boolean in = false;

        for (String s : testList) {

            if (s.equals(var1))
            {
                in = true;
                break;
            }
        } 

        return in;
    } 

我有很多线程同时使用此方法并检查此列表中是否有某个值。它似乎工作正常。但是,我不确定这是否安全。我这样做了吗?它是线程安全的吗?

3 个答案:

答案 0 :(得分:3)

只要没有线程正在修改列表而其他线程正在读取它,它就是线程安全的。

如果您在列表中使用迭代器,它们将会快速失败&#34; (如在throw ConcurrentModificationException中)如果在它们下面修改了列表。其他访问方法(即get(n))不会抛出异常,但可能会返回意外结果。

ListArrayList的Javadoc详细介绍了这一点,您应该仔细研究。

答案 1 :(得分:2)

ArrayList不是线程安全对象。它现在可能对您有用,但一般来说,在使用线程时,您应该确保使用可以按预期使用线程的线程安全对象。

您可以使用Collections.synchronizedList()

testList = Collections.synchronizedList(new ArrayList<String>());

答案 2 :(得分:0)

只要你能保证没有人写信给列表,那就安全了。

请注意,即使列表为staticfinal,代码本身也不保证列表永远不会被修改。我建议使用Collections.unmodifiableList()代替,因为它保证不会在列表中添加或删除任何元素。

顺便说一句,您可以将代码重写为:

public static boolean isInList(String var1) {
    for (String s : testList) {
        if (Objects.equals(s, var1)) {
            return true;
        }
    } 
    return false;
}

或只是

testList.contains(var1);