我正在阅读B. Goetz Java Concurrency In Practice,现在我正在为现有的线程安全类添加功能。他说:
Vector的同步策略由其规范确定,因此 BetterVector不会遇到这个问题。
@ThreadSafe
public class BetterVector<E> exends Vector<E>{
public synchronized boolean putIfAbsent(E x){
boolean absent = !contains(x);
if(absent)
add(x);
return absent;
}
}
所以,我试图找出自己Vector
的同步政策并且只能找到
与新的集合实现不同,Vector是同步的。
这是否意味着它被这个对象同步了?或者它可能意味着任何(可能是私有的)对象的同步。如果是这样,BetterVector<E>
非常脆弱,因为它取决于同步策略的当前实现,甚至没有明确指定。
答案 0 :(得分:1)
这是一个非常好的问题。你似乎没有指定同步Vector
的方式。 (至少,我找不到规范)。
但是,当前实现在对象本身上同步,而不在内部对象上同步。虽然此实施可能随时发生变化,但不太可能发生。代码太多可能依赖于当前的实现。改变可能会破坏所有类型的东西。我怀疑代码维护者会冒这个风险。
我的猜测是,依赖于当前实现的代码在理论上非常脆弱,实际上由于相当保守的代码维护和公开监督Java开发过程而几乎没有风险。
答案 1 :(得分:1)
我不太明白你的术语“同步政策”。 synchronized
关键字的定义可以在https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html的Java语言规范中找到。
同步方法(第8.4.3.6节)在调用时自动执行锁定操作;在锁定操作成功完成之前,它的主体不会执行。如果该方法是实例方法,则它会锁定与调用它的实例关联的监视器(即,在执行方法主体期间将被称为this的对象)。如果方法是静态的,它将锁定与Class对象关联的监视器,该对象表示定义方法的类。如果方法的主体的执行正常或突然完成,则会在同一监视器上自动执行解锁操作。
如何将锁定转换为OS级别调用取决于JVM实现。但是,由于此类关键字的行为必须如上所述在Java语言规范中定义(否则此JVM不遵循Java标准),因此保证编写此类语句的Java程序员将实现他想要的结果,即此类方法是使用synchronized
关键字时线程安全。