2015-07-04 12 views
7

synchronized ist nicht Bestandteil der Methodensignatur. Aber wenn wir eine Methode überschreiben, ist es nicht nur die Methodensignatur, die entscheidet, ob die überschriebene Methode kompiliert wird oder nicht.Warum "synchronisiert" keine Rolle im Polymorphismus spielt

Zum Beispiel können wir nicht eine geprüfte Ausnahme

hinzufügen oder erweitern Warum synchronized keine Rolle bei der Polymorphismus haben. Eine synchronized Methode sollte nicht außer Kraft gesetzt werden synchronized setzen. Da die Person, die eine Superklassenvariable verwendet, denken könnte, dass alle Methoden Thread-sicher sind.

Aber eine nicht synchronisierte Methoden sollten mit synchronized überschrieben werden, da es mehr Funktionalität hinzufügt, aber auf der anderen Seite Benutzer keine Fehler außer Zeitverzögerung auftreten.

Ich suche eine logische Erklärung, die ein wenig Licht auf "warum ist so konzipiert" werfen kann.

Antwort

5

Sie können sehen, JDK-4294756 für eine Erklärung ist es OK für eine Methode, um eine andere überschreiben, ohne die synchronized Modifikator zu erhalten. In diesem Fehlerbericht wurde nach einer Warnung gefragt, die vom Compiler angezeigt werden soll, wenn eine Methode eine synchronized-Methode überschreibt, sich jedoch nicht selbst als synchronized deklariert und als "Nicht reparieren" geschlossen wird. Der Hauptgrund ist die folgende:

Die Verwendung des synchronisierten Modifikator sowie andere Synchronisation über explizite ‚synchronisiert‘, bilden einen Teil der Umsetzung eines durch eine Klasse repräsentiert Abstraktion ist, und ein alternative Implementierung erfasst in einer Unterklasse kann eine andere Synchronisationsstrategie verwenden, um implementieren äquivalente Semantik. Als Beispiel betrachten wir den Fall, in dem ein kleiner kritischer Abschnitt (geschützt durch eine synchronisierte Anweisung) innerhalb einer größeren unsynchronisierten Methode eine kleinere Methode ersetzt, die in ihrer Gesamtheit durch einen synchronisierten Methodenmodifikator geschützt war.

Also die Abwesenheit eines synchronized Modifizierer bedeutet nicht unbedingt, dass die Methode nicht Thread-sicher ist. Fadensicherheit kann innerhalb der Methode feinkörnig sein.

9

Eine "synchronisierte" Methode sollte nicht außer Kraft gesetzt werden, ohne "synchronisiert" zu setzen.

Falsch. Eine Basisklasse ist möglicherweise nicht threadsicher, aber eine Unterklasse kann eine eigene Synchronisation haben, z. B. eine Sperre, eine lockfreie threadsichere Datenstruktur usw. Nicht alle threadsicheren Methoden sind synchronisiert und nicht alle synchronisierten Methoden sind fadensicher.

Das gleiche in der anderen Richtung gehen kann (kann aber auch andere Prinzipien brechen, je nach Fall)

synchronized nicht eine objektorientierte Sache ist, sondern vielmehr eine Laufzeit/Ausführung Phänomen, und eine Implementierung Detail. Alles, was es tut, ist acquire a monitor der gleiche Weg synchronized(this){ } (oder die Synchronisierung auf dem java.lang.Class-Objekt, wenn statische) würde. Als Implementierungsdetail macht es keinen Sinn, OOP-Überlegungen zu berücksichtigen.

Hinweis: Dies bedeutet nicht, dass eine Kompilierungszeit Annotation wie @ThreadSafe keinen Sinn macht. Es tut dies, da es den Vertrag der Methode als Thread-sicher bezeichnet. synchronized tut dies nicht.

+0

Eine "synchronisierte" Methode sollte nicht außer Kraft gesetzt werden, ohne "synchronisiert" zu setzen. Ich frage das, warum es nicht so gestaltet ist. Ich sage nicht, dass es so funktioniert. – Onki

+2

@ user3610891 Das sagen Sie in Ihrer ursprünglichen Frage. Ich erkläre, dass es nicht wahr ist, da dies ein Schlüssel zur Beantwortung Ihrer Frage ist. I – hexafraction

+0

Sie sagen also, dass eine synchronisierte Methode in einen synchronisierten Block konvertiert wird? – Onki

1

Lassen Sie mich es eine andere Art und Weise setzen:

Angenommen, wir zwei Klassen haben:

class Foo { 
    public synchronized void doSomething(...) { ... } 
} 

class Bar extends Foo { 
    public void doSomething(...) { ... } 
} 

Foo und Bar sind verschiedenen Klassen. foo.doSomething(...) und bar.doSomething(...) sind verschiedene Methoden.

Das synchronized Schlüsselwort ist nicht dort zum Wohle des Anrufers: Es sagt nichts über das, was foo.doSomething(...) tut. Das Schlüsselwort synchronized ist nur ein Detail davon, wie diese Methode implementiert ist.

Die Klasse Foo benötigt ihre doSomething(...)-Methode, um synchronisiert zu werden, um ihren API-Vertrag in einer Multithread-Umgebung korrekt zu erfüllen. Die bar.doSomething(...) Methode ist anders implementiert und benötigt keine Synchronisation.

Solange eine Bar Instanz verwendet werden kann, wo immer eine Foo Instanz gesucht wird, sollte jeder glücklich sein. Es gibt keinen Grund, warum der Aufrufer die Methode synchronisieren soll: Der Aufrufer sollte nur die Methode arbeiten wollen.

Verwandte Themen