2016-02-16 7 views
12

Warum sind wait, notify und notifyAll Methoden in Object platziert, nicht in einer separaten Klasse?Warum wait() und notify() sind nicht in einer speziellen Klasse?

Hinweis, diese Frage geht nicht um sie zu Thread Klasse zu bewegen, frage ich mich nur, warum sie Object Wurf, nicht einige neue Monitor Klasse.

Ich sehe die folgenden Nachteile dieser Idee:

  • Wir werden nicht in der Lage sein, unsere für-andere Zwecke als Monitore Felder zu verwenden. Dies scheint jedoch dem Prinzip der Modularität zuzustimmen.
  • Synchronisierte Methoden erfordern jetzt einige Hack mit generierten ausgeblendeten Feldern (wie in Schließungen), als this und <MyClass>.class werden nicht gültige Monitore.

So konnten wir 5 Methoden von jedem Objekt mit ein wenig Wehe weg bewegen. Oder nicht?

+0

'Ich frage mich nur, warum sie Object, nicht einige neue Monitor-Klasse.' - konzeptionell, tun sie intern, aber der Monitor ist einzigartig für jedes Objekt. Siehe die doppelte Antwort (obwohl es sich auf "Thread" bezieht) –

+1

@biziclop Genau. Als Per Brinch Hansen die ersten Parallelkonstrukte von Java sah, schrieb er: "Ich habe eindeutig umsonst gearbeitet". Sie scheinen von den unschönen "Sleep/Wakeup()" Interna von UNIX entlehnt worden zu sein. – EJP

+0

* "So könnten wir 5 Methoden von jedem Objekt mit ein bisschen Weh wegziehen" * AFAIK technisch existieren diese Methoden nur einmal, nicht einmal für jede Instanz. – m0skit0

Antwort

7

Die wirkliche Antwort ist, dass es ein Fehler war, endlich anerkannt mit der Schaffung der Condition Klasse, die genau das tut, was Sie erwarten würden. (Obwohl, da es ein Objekt ist, besteht eine Möglichkeit, dass Sie versehentlich wait() auf sie statt await(), mit urkomischen Folgen ... aufrufen werden)

Apart haben Sie bereits von den Dingen, in denen eine Bindung Das Überwachen jedes einzelnen Objekts macht es auch unmöglich, wirklich unveränderbare Objekte in Java zu haben.

So können Sie dies zum Beispiel tun:

class A { 
    void foo() { 
     synchronized((Integer)42) { 
     ... 
     } 
    } 
} 

class B { 
    void foo() { 
     synchronized((Integer)42) { 
      ... 
     } 
    } 
} 

die gleiche Box integer Rückkehr für 42 jedes Mal, kein Problem, wenn das Objekt unveränderlich war sein soll. Aber es ist nicht, es hat einen veränderlichen Zustand: seinen Monitor, der diese Art der Synchronisation ermöglicht. Besonders schlimm ist, dass Sie einen Mutex zwischen zwei Code-Stücken erstellt haben, die auf den ersten Blick unabhängig erscheinen.

+0

Bemerkenswerte Antwort. Ich wollte extra +1 hinzufügen zum Beispiel mit Caching Integer – Martoon

+1

@Martoon Als Übung schrieb ich [ein Paar Eingabe/Ausgabe-Streams] (http://pastebin.com/r2bKbXfE), die dies ausnutzen, um miteinander zu kommunizieren. Das wirklich Gruselige ist, dass sie überall funktionieren, wo du sie in die gleiche VM legst, zwei separate Web-Apps im selben Container. – biziclop

0

Da jedes Objekt als Monitor fungieren kann.

+0

Ja, aber die Frage ist, warum nicht eine separate Klasse haben. – m0skit0

0

1) Warten und benachrichtigen ist nicht nur normale Methoden oder Synchronisation Dienstprogramm, mehr als das sind sie Kommunikationsmechanismus zwischen zwei Threads in Java. Und die Objektklasse ist der korrekte Ort, um sie für jedes Objekt verfügbar zu machen, wenn dieser Mechanismus nicht über irgendein Java-Schlüsselwort wie synchronisiert verfügbar ist. Denken Sie daran, synchronisierte und warte Benachrichtigung sind zwei verschiedene Bereich und nicht verwechseln, dass sie gleich oder verwandt sind. Synchronisiert ist, wechselseitigen Ausschluss zu bieten und Thread-Sicherheit der Java-Klasse wie Race Condition zu gewährleisten, während wait und notify Kommunikationsmechanismen zwischen zwei Threads sind.

2) Sperren werden auf Objektbasis verfügbar gemacht, was ein weiterer Grund dafür ist, dass wait and notify in der Object-Klasse und nicht in der Thread-Klasse deklariert wird.

3) Um in den kritischen Bereich des Codes zu gelangen, benötigt Threads eine Sperre und sie warten auf die Sperre. Sie wissen nicht, welche Threads die Sperre halten. Sie wissen nur, dass die Sperre von einem Thread gehalten wird und sie warten sollten for lock, anstatt zu wissen, welcher Thread sich innerhalb des synchronisierten Blocks befindet, und ersucht sie, die Sperre aufzuheben. Diese Analogie passt zu "Warten" und "Benachrichtigen", anstatt in Java zu fädeln.

mit ref: http://javarevisited.blogspot.in/2012/02/why-wait-notify-and-notifyall-is.html

1

Ein Vorteil ist, dass Sie einfach auf einem Referenz synchronisieren kann es einen redundanten Monitor ohne Erstellung:

synchronized (myList) { 
    myList.add(0); 
} 

vs

private final Object mySpecialMonitor = new Object(); 

syncronized(mySpecialMonitor) { 
    myList.add(0); 
} 

wäre es funktioniert nicht, wenn alle Synchronisation in einer separaten Klasse war.

+0

Ja, es ist der erste Fehler, den ich aufgelistet habe. Aber auf diese Weise zu denken, führt uns dazu, 'ReentrantLock.lock()', 'unlock()', 'StringBuilder.append()' zu verschieben, ich weiß nicht, was sonst noch zur 'Object'-Klasse gehört, was nicht zu sein scheint eine nette Wendung. Ich meine, "Objekt" -Klasse ist nicht für die Synchronisation spezialisiert – Martoon

+2

Ich würde dies nicht als Vorteil bezeichnen. Da der sichere Weg der Synchronisation nicht darin besteht, ein öffentlich sichtbares Objekt zu erstellen, wird meistens ein dediziertes Sperrobjekt in einem 'privaten finalen' Feld erzeugt. – biziclop

Verwandte Themen