2013-03-12 10 views
39

Powiedzmy mam zsynchronizowany sposób na jakiejś klasy:nadrzędnym zsynchronizowanych metod w Javie

abstract class Foo { 
    public synchronized void foo() { // synchronized! 
     // ... 
    }; 
} 

i overrode go bez pomocą zsynchronizowane modyfikator:

class Bar extends Foo { 
    @Override 
    public void foo() {    // NOT synchronized! 
     super.foo(); 
     // ... 
    } 
} 

Mam parę szczegółowe pytanie dotyczące tego scenariusza:

  1. Czy zastąpiona metoda b e także niejawnie zsynchronizowane?
  2. Jeśli nie, czy będzie można zsynchronizować telefon super?
  3. Jeśli nie ma numeru super, czy wszystko zostanie zsynchronizowane?
  4. Czy istnieje sposób na wymuszenie stosowania metody nadpisującej w celu użycia synchronized (zauważyłem, że abstrakcyjne definicje metod lub definicje metod w interfejsie nie zezwalają na synchronizowane słowo kluczowe)?
+0

Zobacz http://stackoverflow.com/questions/12684850/how-can-i-ensure-that-an- overridden-method-is-synchronized – rgettman

+1

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4294756 Synchronizacja nie jest częścią sygnatury metody, ale częścią implementacji metody. – flup

Odpowiedz

41
public synchronized void foo() { // synchronized! 
    // ... 
}; 

jest zasadniczo taka sama, jak:

public void foo() { 
    synchronized (this) { // synchronized! 
     // ... 
    } 
}; 

Ten ostatni jest bardziej wyraźne, więc chciałbym ogólnie sugerują za pomocą tego formularza. Lub lepiej, używając blokady, która jest prywatnym polem, a nie "zewnętrznym" obiektem.

Tak: 1. Nie 2. Tak. 3. Nie. 4. Zaznaczyć metodę final i wywołać metodę protected, która może zostać nadpisana.

public final void foo() { 
    synchronized (this) { 
     fooImpl(); 
    } 
}; 
protected void fooImpl() { 
    // ... 
} 

Jak zawsze, może ci się przydać lepiej delegowanie zamiast podklasy.

+0

+1 To świetny sposób patrzenia na to! Dzięki! –

+0

Używanie fooImpl jest poprawnym sposobem i wciąż przypomina mi [ClassLoader.loadClassInternal] (http://bugs.sun.com/view_bug.do?bug_id=4670071) Oczywiście można oszukiwać w fooImpl przez 'monitorExit' /' moniorEnter' – bestsss

+0

@bestss Nawet jeśli napiszesz własny kod bajtowy, monitor enter/exit powinien zostać dopasowany. (IIRC istnieje pewna szczególna swoboda w specyfikacji, ale nie ma żadnej rozsądnej implementacji). Chociaż 'fooImpl' może' czekać'. –

20

Niepowodzenie w użyciu zsynchronizowane, gdy nadpisanie zsynchronizowanej metody może spowodować błędy w czasie wykonywania. Jako zabezpieczenie istnieje moduł sprawdzający Eclipse, który można włączyć, aby wykryć ten warunek. Domyślną wartością jest "ignore". "Ostrzeżenie" to również ważny wybór. preferences

która będzie produkować tę wiadomość:

enter image description here

enter image description here

+3

+1 Dobrze wiedzieć! –

Powiązane problemy