Tôi có siêu lớp Point
và phương thức synchronized
draw()
. Các lớp con của số Point
có kế thừa synchronized
nếu tôi ghi đè phương thức draw()
vào chúng hay tôi phải luôn viết nó?Được đồng bộ kế thừa trong Java?
Trả lời
Không, bạn sẽ luôn phải viết synchronized
. Nếu bạn gọi phương thức đồng bộ của lớp siêu này tất nhiên sẽ là một cuộc gọi được đồng bộ hóa. synchronized
không phải là một phần của chữ ký phương thức.
Xem http://gee.cs.oswego.edu/dl/cpj/mechanics.html để biết mô tả chi tiết từ Doug Lea, Java threading boss (hoặc hơn).
Có thể làm rõ một chi tiết: cho dù cuộc gọi phương thức đã cho có được đồng bộ hay không phụ thuộc vào loại động của đối tượng mà nó được gọi, không phải kiểu tĩnh. Tức là, nếu 'foo()' là 'đồng bộ' trong' Derived' nhưng không phải trong 'Base', và bạn gán một' Derived' vào biến 'Base' và gọi' foo() 'trên đó, cuộc gọi đó sẽ được đồng bộ hóa. Điểm này là ẩn trong 8.4.3.6 của spec ngôn ngữ (mà nói một phương thức 'sync' tương đương với câu lệnh' synchronized' trong phương thức đó), nhưng tôi không thể tìm thấy nó được viết ra ở bất cứ nơi nào khác. Runnable demo [ở đây] (http://runnable.com/U4zBThIj5WNju2g2/). – mrec
Bạn có thể kiểm tra xem nó cho mình bằng cách viết này:
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;
}
}
Và kiểm tra lớp
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
}
}
Trên máy tính của tôi nó là 137.099 thay vì 200000.
Cách dễ dàng hơn để kiểm tra sẽ là kiểm tra trên ['Thread.holdsLock (this);'] (http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#holdsLock% 28java.lang.Object% 29) theo phương pháp ghi đè –
Không trả lời câu hỏi. Mã thử nghiệm chỉ có thể làm lộ một lỗi hoặc một thời gian bất thường do một cái gì đó khác ngoài đồng bộ hóa. Câu trả lời là được tìm thấy trong đặc tả ngôn ngữ. – EJP
@EJP Lúc đầu, tôi nghĩ bạn đã sai. Sau đó, tôi nhận ra bạn thực sự đúng, nhưng khá bi quan ... – Timo
thể trùng lặp của [Trọng một cách đồng bộ phương pháp] (http://stackoverflow.com/questions/10173345/overriding-a-synchronized-method) – Raedwald