2017-05-19 31 views
-1

以下是有关如何防止竞争条件的答案。 What is a race condition?不可变对象如何有助于防止竞争条件

最好的事情是创建无副作用和无状态 功能,使用immutables尽可能。但这并不总是 可能。因此,使用java.util.concurrent.atomic,并发数据 结构,适当的同步和基于角色的并发将帮助 。

这个答案说尽可能地使用immutables。我很困惑不变的对象如何防止竞争条件。

+0

如果一个对象是不可变的,那么多少个线程访问它并不重要。 –

+4

如果您无法修改内容,则不能进行并发修改。 – user2357112

回答

1

只有当至少有一个线程被允许写/改变实例的状态时才会出现竞争条件。 不可变实例只读,它们的状态不能被改变,因此,所有线程只读的对象的状态,并且看到相同的值(一个或多个)

0

data race时发生“两个或多个线程...同时访问相同的内存位置,并且至少有一个访问用于写入,并且这些线程不使用任何排他锁来控制对该内存的访问。“

如果数据不可变,就不会有数据竞争,因为可能没有写入权限。

另外,Java Memory Model guarantees

一旦对象被构造中,分配给在构造最终字段中的值将是可见的所有其它线程不同步。

0

当计算结果取决于评估表达式和语句的顺序时,会出现竞争条件。

如果对表达式和语句的评估改变状态,产生副作用,结果可能会有所不同。

如果代码中的所有内容都是不可变的,那么在对表达式和语句进行评估时,不会改变状态,也不会产生副作用。因此评估顺序不会影响最终结果。

考虑下面的代码:

Map<String, Integer> map = Collections.singletonMap("key", 0); 

public void increment() { 
    int val = map.get("key); 
    map.put("key", val + 1); 
} 

如果两个线程执行方法increment()的每个语句同时,同时读同一价值0两者放在同一增加值1map。因此结果将是1

如果两个线程(偶然)将执行所有语句连续一个线程会读取值0,并把价值1而其他线程会读取值1,把价值2

现在,如果地图将是不可改变的,两个线程将执行以下方法:

public void logMap() { 
    System.out.println("Key has value " + map.get("key")); 
} 

结果将始终是相同的,因为没有副作用(除了由所做的更改System.out.println)影响计算。