Java 实践中的并发>;清单4.13

Java 实践中的并发>;清单4.13,java,concurrency,thread-safety,Java,Concurrency,Thread Safety,以下是第72页的一个片段: @ThreadSafe public class BetterVector<E> extends Vector<E> { public synchronized boolean putIfAbsent(E x) { boolean absent = !contains(x); if (absent) add(x); return absent; } } @ThreadSafe 公共类BetterVe

以下是第72页的一个片段:

@ThreadSafe
public class BetterVector<E> extends Vector<E> {
  public synchronized boolean putIfAbsent(E x) {
    boolean absent = !contains(x);
    if (absent)
      add(x);
    return absent;
  }
}
@ThreadSafe
公共类BetterVector扩展向量{
公共同步布尔putIfAbsent(E x){
布尔缺席=!包含(x);
如果(缺席)
加(x);
缺席返回;
}
}

根据Brian的说法,上面的类是线程安全的。但正如您所看到的,
ex
实际上是一个可变类。如果将
缺席
评估为
真实
后,
x
的值发生变化,会发生什么情况?这难道不是一种违规行为,可能会导致相当严重的bug吗?

是的,你是对的。但这不是线程代码或并发性的问题。这是一个涉及引用和指针的计算机科学类型的问题。参考点指向一个对象。如果您像Java一样传递引用,那么这些引用可以用来访问底层对象。

您可以在单线程执行中复制该问题。添加两个元素,然后将其中一个更改为与另一个相同。所以这并不是关于线程安全的。“线程安全”并不意味着“在这段代码中你不会有任何类型的bug”。顺便说一句,“但是正如你所看到的,ex确实是一个可变类。”这并不完全正确,因为你看不到。它也可以是一个不可变的类。
E
没有绑定到任何类,因此它本身并不不安全。只有当你不知道自己在做什么时,它才会变得不安全。