我知道这显然是一种竞争条件。但是可能发生的事情是什么?
class Blah {
List<String> stuff;
public List<String> getStuff() {
return stuff
}
public void setStuff(List<String> newValue) {
this.stuff = newValue
}
}
b = new Blah();
// Thread one
b.setStuff(getListFromSomeNetworkResource());
for (String c : b.getStuff()) {
// Work with c
}
// Thread two
b.setStuff(getListFromSomeNetworkResource());
for (String c : b.getStuff()) {
// Work with c
}
我知道这是竞争条件,不会写这样的代码。但是,我如何说服别人不要?
更新
假设:
getListFromSomeNetworkResource()
始终返回新的ArrayList
。大小可以是0或更多。getListFromSomeNetworkResource()
是线程安全的。答案 0 :(得分:0)
这会抛出RuntimeException吗?
不,如果 getListFromSomeNetworkResource()
是线程安全的,并且不会返回null
。
这个段错误jvm?
这个段错误可以吗?
是否依赖于处理器。如果它是Intel Xeon处理器怎么办?
没有
这会抛出NullPointer异常吗?
仅当getListFromSomeNetworkResource()
可以返回null
时。
是的,这可能会发生。如果函数实际返回不同的值
,则线程2可以读取线程1设置的内容,反之亦然
答案 1 :(得分:-1)
危险将是如下的排序:
b.setStuff(getListFromSomeNetworkResource());
b.setStuff(getListFromSomeNetworkResource());
b.stuff.iterator()
(通过b.getStuff()
,在 循环的开头)在这种情况下,线程1 可以迭代线程二集的列表。从第二个线程到第一个线程的那个发布没有任何同步就完成了 - 这是一个数据竞争。假设列表本身不是线程安全的,可能会发生很多事情。主要问题是由于数据竞争,一些列表的状态对于第一个而不是全部可见。
n
个元素。但是来自调整大小的新数组没有完成,所以最终得到了一个ArrayIndexOutOfBoundsException 它不应该导致任何段错误:那些只能来自JVM中的错误,但从不会在代码中出现错误。
它可能取决于处理器,因为处理器可能有不同的处理方式,例如将内存从一个CPU缓存刷新到另一个CPU缓存 - 这是不安全发布可能导致您只看到一些数据的原因之一thread写道,来自另一个线程。有办法强迫这些缓存刷新;在Java中指定它们的方法是通过各种数据同步机制(获取锁,使用volatile字段等)。