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 hs 的唯一所有者吗?

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

首先,看看这个SO关于不使用Vector的原因。话虽如此:

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

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

如果需要保护对象的状态,则需要尽可能接近该状态。Java没有线程拥有对象的概念。因此,在您的情况下,如果要防止许多线程同时调用setSameString,则需要声明方法synchronized

我推荐Brian Goetz关于并发的优秀书籍,以获取有关该主题的更多信息。

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

最新更新