Java 中的线程安全 类 解释

Thread-safe classes explanation in Java

让我们考虑一下这种情况:

public class A {
    private Vector<B> v  = new Vector<B>();
}

public class B {
    private HashSet<C> hs = new HashSet<C>();
}

public class C {
    private String sameString;

    public void setSameString(String s){
          this.sameString = s;
    }
}

我的问题是:

  1. Vector 是线程安全的,所以当一个线程调用它时,例如,get(int index)方法这个线程是HashSet[的唯一所有者吗? =27=]hs?

  2. 如果线程在 v 上调用 get(int index) 并且它获得一个 B 对象。然后这个线程获取一个C对象,调用setSameString(String s)方法,这样写线程安全吗?或者需要Lock这样的机制?

首先,看一下 this SO 使用 Vector 的原因。也就是说:

1) Vector 锁定每个操作。这意味着它一次只允许一个线程调用它的任何操作(获取、设置、添加等)。没有什么可以阻止多个线程修改 Bs 或其成员,因为它们可以在不同时间获得对它们的引用。 Vector(或具有类似同步策略的 类)的唯一保证是没有两个线程可以同时修改向量并因此进入竞争条件(这可能会抛出 ConcurrentModificationException and/or 导致未定义的行为);

2) 如上所述,没有什么可以阻止多个线程同时访问 Cs,因为它们可以在不同时间获得对它们的引用。

如果你需要保护一个对象的状态,你需要尽可能接近状态。 Java 没有线程 拥有 对象的概念。所以在你的情况下,如果你想防止许多线程同时调用 setSameString ,你需要声明方法 synchronized.

我推荐 Brian Goetz 关于并发的优秀 book 以了解更多关于该主题的内容。

情况2。它不是线程安全的,因为多个线程可以同时访问数据。如果你想获得更好的性能,可以考虑使用读写锁。 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html#readLock()