Java中的线程安全类解释

时间:2015-01-14 00:23:12

标签: java thread-safety

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

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等机制?

非常感谢您的解释。

2 个答案:

答案 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()