让我们考虑一下这种情况:
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
等机制?
非常感谢您的解释。
答案 0 :(得分:4)
首先,请查看this SO关于不的原因以使用Vector
。话虽如此:
1)Vector
锁定每个操作。这意味着它一次只允许一个线程调用其任何操作(获取,设置,添加等)。没有什么可以阻止多个线程修改B
或其成员,因为他们可以在不同的时间获得对它们的引用。 Vector
(或具有类似同步策略的类)的唯一保证是没有两个线程可以同时修改向量,从而进入竞争条件(可能抛出ConcurrentModificationException
和/或导致未定义行为);
2)如上所述,没有什么能阻止多个线程同时访问C
,因为他们可以在不同的时间获得对它们的引用。
如果需要保护对象的状态,则需要尽可能接近状态。 Java没有线程拥有对象的概念。所以在你的情况下,如果你想阻止许多线程同时调用setSameString
,你需要声明方法synchronized
。
我推荐Brian Goetz关于并发性的优秀book以获取有关该主题的更多内容。
答案 1 :(得分:0)
在第2种情况下。它不是线程安全的,因为多个线程可以同时访问数据。如果要获得更好的性能,请考虑使用读写锁。 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html#readLock()