假设,我有静态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(),它会得到正确的值吗?
如果没有那么我该怎么办?
答案 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();
}
}