问的问题没有意义。您问的是向对象添加方法,而不是向类添加方法——您不能在 Java 中这样做。Collections.synchronizedList
选择 List 的类——它是java.util.Collections.SynchronizedRandomAccessList
or ...SynchronizedList
。此外,它们中的每一个都是包私有的,因此您无法扩展它们。
但是,假设您确实有一个类似于那些提供的实现:
public class SyncedList<E> implements List<E> {
private final List<E> delegate;
public SyncedList(List<E> delegate) { this.delegate = delegate; }
@Override
public synchronized boolean add(E e) {
return delegate.add(e);
}
@Override
public synchronized void clear() {
delegate.clear();
}
// ... etc
现在你扩展这个类:
public class MySyncedList<E> extends SyncedList<E> {
...
您现在的问题是:我们与覆盖的方法有什么关系?答案是……这取决于!
要记住的一般规则是,被覆盖的方法不会继承其 super 的synchronized
修饰符。但你可能不需要它。以下是一些场景:
场景 1:根本不调用super
方法
例子:
@Override
public void clear() {
throw new UnsupportedOperationException();
}
在这种情况下,应该清楚(双关语警告!)您不需要任何同步,因为没有什么要同步的。(简单的例子,但很容易摆脱。)
场景 2:调用一个super
方法而不触及其他可变状态
例子:
private final E dontAllow; // assume this is set in the constructor
@Override
public boolean add(E e) {
if (Objects.equals(e, dontAllow))
throw new IllegalArgumentException("can't add element: " + e);
super.add(e);
}
在这种情况下,您实际上不需要 synchronize add
。调用super.add(e)
将保留其同步,并且您没有触及任何其他可变状态,因此没有任何额外的同步。
场景 3:调用一种super
方法但也触及可变状态
例子:
private E lastAdded = null;
@Override
public synchronized boolean add(E e) {
boolean result = super.add(e); // do this first in case it throws an exception
lastAdded = e;
return result;
}
public synchronized E getLastAdded() {
return lastAdded;
}
这里我们添加了额外的状态,所以我们必须同步它!请注意,在这种特殊情况下,您也可以设置lastAdded
volatile 并且不使任一方法同步——但在其他情况下,这可能是不可能的。
场景4:调用不止一种方法super
例子:
public synchronized void add(E e) {
if (indexOf(e) >= 0)
return false;
return super.add(e);
}
假设您关心原子性,那么您确实需要同步。它不是继承自super.add
. indexOf
方法 (和) 中的每个调用super.add
都是同步的,但您需要额外的原子性。
(更准确地说,您需要在监视器上同步时调用这两个方法,这也应该是每个方法使用的监视器。在这种情况下,这两个方法是同步的,因此监视器只是this
,这是同步方法同步的内容。)
最后的想法
即使您不必同步覆盖的方法,如果它读取或写入状态(例如上面的场景 2,如果您采用该volatile lastAdded
方法,则为 3)可能是一个好主意。所有其他的 mutator/accessor 方法都是同步的,所以如果一个方法不同步,你的 API 会看起来很奇怪。人们会问,“哎,不add
应该同步吗?” 你必须说服他们不需要这样。更重要的是,您实际上不会获得任何东西,因为该方法最终会在super
调用时进行同步。
我没有在上面介绍所有可能的情况,但希望这能让你了解事情是如何运作的。