线程安全的静态功能

时间:2014-04-11 07:15:21

标签: java android multithreading static thread-safety

假设,我有静态setter和getter,如:

private static List<String> result = new ArrayList<String>();

public static void setResult(String result) {
    result.add(result);
}

public static List<String> getResult() {
    return result;
}

public static void clearResult() {
    result.clear();
}

我想知道setResult()是否从一个线程运行并且getResult()是从不同的线程调用而clearResult()是从另一个线程调用,然后会发生什么?这个函数是线程安全的吗? getResult()会返回正确的值吗?

还有一件事,在中期,如果我调用clearResult()和线程连续检查getResult(),它会得到正确的值吗?

如果没有那么我该怎么办?

3 个答案:

答案 0 :(得分:3)

所有三种方法都在ArrayList上运行,这不是一个线程安全的结构。因此,您的方法也不是线程安全的。来自JavaDoc:

  

注意此实施未同步。如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。

以这种方式更改以下行,您应该没问题:

private static List<String> result = Collections.synchronizedList(new ArrayList<String>());

答案 1 :(得分:2)

首先ArrayList 不是线程安全的,它不应该以多线程方式直接使用而不进行任何同步,因为它可能会意外失败。

您可以使用Collections.synchronizedList(arrayList);并依赖于线程安全。

但是在带有锁的静态arraylist上可能存在很多争用,所以如果你经常移动而不是改变列表,你甚至可以使用CopyOnWriteArrayList

Collections.synchronizedList()

的用法
private static List<String> result = Collections.synchronizedList(new ArrayList<String>());

参考文献:

答案 2 :(得分:0)

您可以将List与保护对象同步:

private static List<String> result = new ArrayList<String>();
private static Object       guard  = new Object();

public static void setResult(String result) {
    syncronized (guard) {
        result.add(result);
    }
}

public static List<String> getResult() {
    syncronized (guard) {
        return result;
    }
}

public static void clearResult() {
    syncronized (guard) {
        result.clear();
    }
}