Ho la superclasse Point
e un metodo synchronized
draw()
. Le sottoclassi di Point
erediteranno synchronized
se eseguo l'override del metodo draw()
o devo sempre scriverlo?È sincronizzato ereditato in Java?
risposta
No, sarà sempre necessario scrivere synchronized
. Se chiami il metodo sincronizzato della super classe, questa sarà ovviamente una chiamata sincronizzata. synchronized
non fa parte della firma del metodo.
Vedere http://gee.cs.oswego.edu/dl/cpj/mechanics.html per la descrizione dettagliata di Doug Lea, capo di threading Java (o così).
Forse chiarire un dettaglio: se una determinata chiamata di metodo è sincronizzata o meno dipende dal tipo dinamico dell'oggetto su cui è chiamato, non dal tipo statico. Cioè, se 'foo()' è 'sincronizzato' in' Derivato' ma non in 'Base', e si assegna un' Derivato' a una variabile 'Base' e si chiama' foo() 'su di esso, quella chiamata sarà essere sincronizzati Questo punto è implicito in 8.4.3.6 delle specifiche del linguaggio (che dice che un metodo 'synchronized' è equivalente a un'istruzione' synchronized' all'interno di quel metodo), ma non riuscivo a trovarlo scritto altrove. Demo eseguibile [qui] (http://runnable.com/U4zBThIj5WNju2g2/). – mrec
Potete controllare voi stessi scrivendo questo:
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;
}
}
E prova di classe
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
}
}
Sulla mia macchina era 137099 invece di 200000.
il modo più semplice per testare sarebbe testare su ['Thread.holdsLock (this);'] (http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#holdsLock% 28java.lang.Object% 29) nel metodo sottoposto a override –
Non risponde alla domanda. Il codice di test potrebbe semplicemente esporre un bug o un'anomalia temporale dovuta a qualcosa di diverso dalla sincronizzazione. La risposta si trova nelle specifiche del linguaggio. – EJP
@EJP All'inizio ho pensato che ti fossi sbagliato. Poi ho capito che avevi ragione, ma piuttosto pessimista ... – Timo
possibile duplicato di [Override di una sincronizzato metodo] (http://stackoverflow.com/questions/10173345/overriding-a-synchronized-method) – Raedwald