竞争条件只发生在多个线程同时访问相同资源,并且存在一个或多个线程修改了共享资源,如果多个线程只读共享资源那么不会产生竞争条件。
下面我们通过一个实例来说明当一个共享资源被多个线程访问,但没有线程修改共享资源时不会产生竞争条件。
1 | public class ImmutableValue{ |
请注意 ImmutableValue 提供了一个传入指定 value 的构造函数,一旦对象被创建,该对象没有提供任何修改value值的方法,所以value的值无法被修改。
特别注意:对象引用不是线程安全的
需要注意的是,当一个对象不可变时对象本身是线程安全的,但是对象的引用可能不是线程安全的。举例:
1 | public class Calculator{ |
Calculator 类引用了一个 ImmutableValue 对象,请注意它可以通过 setImmutableValue() 方法和 add() 方法改变了 ImmutableValue 对象的引用。换句话说,即使 ImmutableValue 对象是不可变的,但它也是非线程安全的。ImmutableValue 类是线程安全的,但对象的引用是非线程安全的。所以特别注意:对象的引用可能是非线程安全的。 可以通过给 setImmutableValue() 方法和 add() 方法加锁(使用 synchronized 关键字等)保证线程安全。