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;
}
}
我的问题是:
Vector
是线程安全的,所以当一个线程调用它时,例如,get(int index)
方法这个线程是HashSet
[的唯一所有者吗? =27=]hs?
如果线程在 v 上调用 get(int index)
并且它获得一个 B 对象。然后这个线程获取一个C对象,调用setSameString(String s)
方法,这样写线程安全吗?或者需要Lock
这样的机制?
首先,看一下 this SO 不 使用 Vector
的原因。也就是说:
1) Vector
锁定每个操作。这意味着它一次只允许一个线程调用它的任何操作(获取、设置、添加等)。没有什么可以阻止多个线程修改 B
s 或其成员,因为它们可以在不同时间获得对它们的引用。 Vector
(或具有类似同步策略的 类)的唯一保证是没有两个线程可以同时修改向量并因此进入竞争条件(这可能会抛出 ConcurrentModificationException
and/or 导致未定义的行为);
2) 如上所述,没有什么可以阻止多个线程同时访问 C
s,因为它们可以在不同时间获得对它们的引用。
如果你需要保护一个对象的状态,你需要尽可能接近状态。 Java 没有线程 拥有 对象的概念。所以在你的情况下,如果你想防止许多线程同时调用 setSameString
,你需要声明方法 synchronized
.
我推荐 Brian Goetz 关于并发的优秀 book 以了解更多关于该主题的内容。
情况2。它不是线程安全的,因为多个线程可以同时访问数据。如果你想获得更好的性能,可以考虑使用读写锁。 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html#readLock()
让我们考虑一下这种情况:
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;
}
}
我的问题是:
Vector
是线程安全的,所以当一个线程调用它时,例如,get(int index)
方法这个线程是HashSet
[的唯一所有者吗? =27=]hs?如果线程在 v 上调用
get(int index)
并且它获得一个 B 对象。然后这个线程获取一个C对象,调用setSameString(String s)
方法,这样写线程安全吗?或者需要Lock
这样的机制?
首先,看一下 this SO 不 使用 Vector
的原因。也就是说:
1) Vector
锁定每个操作。这意味着它一次只允许一个线程调用它的任何操作(获取、设置、添加等)。没有什么可以阻止多个线程修改 B
s 或其成员,因为它们可以在不同时间获得对它们的引用。 Vector
(或具有类似同步策略的 类)的唯一保证是没有两个线程可以同时修改向量并因此进入竞争条件(这可能会抛出 ConcurrentModificationException
and/or 导致未定义的行为);
2) 如上所述,没有什么可以阻止多个线程同时访问 C
s,因为它们可以在不同时间获得对它们的引用。
如果你需要保护一个对象的状态,你需要尽可能接近状态。 Java 没有线程 拥有 对象的概念。所以在你的情况下,如果你想防止许多线程同时调用 setSameString
,你需要声明方法 synchronized
.
我推荐 Brian Goetz 关于并发的优秀 book 以了解更多关于该主题的内容。
情况2。它不是线程安全的,因为多个线程可以同时访问数据。如果你想获得更好的性能,可以考虑使用读写锁。 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html#readLock()