【发布时间】:2013-04-06 13:45:16
【问题描述】:
我有超类Point 和synchronized 方法draw()。 Point 的子类是否会继承 synchronized 如果我在其中重写方法 draw() 或者我必须始终编写它?
【问题讨论】:
标签: java inheritance synchronized
我有超类Point 和synchronized 方法draw()。 Point 的子类是否会继承 synchronized 如果我在其中重写方法 draw() 或者我必须始终编写它?
【问题讨论】:
标签: java inheritance synchronized
不,你总是要写synchronized。如果你调用超类的同步方法,这当然是一个同步调用。 synchronized 不是方法签名的一部分。
请参阅http://gee.cs.oswego.edu/dl/cpj/mechanics.html,了解来自 Java 线程老板(左右)Doug Lea 的详细描述。
【讨论】:
foo() 在Derived 中是synchronized 而不是在Base 中,并且您将Derived 分配给Base 变量并在其上调用foo(),则该调用将被同步。这一点隐含在语言规范的 8.4.3.6 中(其中说 synchronized 方法等同于该方法中的 synchronized 语句),但我在其他任何地方都找不到它的拼写。可运行演示here.
您可以通过编写以下代码自行检查:
public class Shape {
protected int sum = 0;
public synchronized void add(int x) {
sum += x;
}
}
public class Point extends Shape{
public void add(int x) {
sum += x;
}
public int getSum() {
return sum;
}
}
和测试类
public class TestShapes {
public final static int ITERATIONS = 100000;
public static void main(String[] args) throws InterruptedException {
final Point p = new Point();
Thread t1 = new Thread(){
@Override
public void run() {
for(int i=0; i< ITERATIONS; i++){
p.add(1);
}
}
};
Thread t2 = new Thread(){
@Override
public void run() {
for(int i=0; i< ITERATIONS; i++){
p.add(1);
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(p.getSum()); // should equal 200000
}
}
在我的机器上是 137099 而不是 200000。
【讨论】:
Thread.holdsLock(this);