2016-10-11 4 views
4

Ich kam vor kurzem in den Quellen von AWTs EventQueue, wo ich dieses Stück Code sah:Wie Thread vergleichen Objekte

final boolean isDispatchThreadImpl() { 
    EventQueue eq = this; 
    pushPopLock.lock(); 
    try { 
     EventQueue next = eq.nextQueue; 
     while (next != null) { 
      eq = next; 
      next = eq.nextQueue; 
     } 
     if (eq.fwDispatcher != null) { 
      return eq.fwDispatcher.isDispatchThread(); 
     } 
     return (Thread.currentThread() == eq.dispatchThread); 
    } finally { 
     pushPopLock.unlock(); 
    } 
} 

Was ringt mir wirklich, dass die Thread-Objekte verglichen werden == verwenden. Bisher habe ich das mit equals(Object) gemacht. Ich habe mich schon this question angesehen, aber die zwei Antworten sind nicht wirklich das, wonach ich suche.

Ist es möglich, dass sich zwei verschiedene Instanzen auf denselben nativen Thread beziehen? Wie sollte ich Thread-Objekte für die Gleichheit vergleichen?

+1

Heh, einer jener amüsanten Situationen, in denen die * Frage * ist in der Tat ein Duplikat, aber die Antworten dort nicht beantwortet die gestellte Frage. :-) –

+3

Der Schlüssel zu Ihrer Frage ist, ob 'Thread.currentThread() == eq.dispatchThread' Ihnen jemals ein anderes Ergebnis geben wird als' Thread.currentThread(). Equals (eq.dispatchThread) '.Und die Antwort ist nein, wird es nie, denn ['Thread.currentThread'] (http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#currentThread--) wird gib niemals 'null' zurück und' Thread' erbt 'gleich' von 'Objekt' und [' Objekt # ist gleich '] (http://docs.oracle.com/javase/8/docs/api/java/lang/Object .html # equals-java.lang.Object-) tut '=='. –

+0

@ T.J.Crowder Ich dachte das Gleiche! ;) – beatngu13

Antwort

6

Ist es möglich, dass sich zwei verschiedene Instanzen auf denselben nativen Thread beziehen?

No.

Nach der Thread Javadoc-:

A Gewinde ist ein Ausführungs-Thread in einem Programm.

Der Lebenszyklus eines Thread Objekt besteht aus drei Phasen:

  • Vor dem start() Aufruf, ein Thread Objekt bezeichnet einen Faden, die noch erstellt werden muss. Und könnte nie geschaffen werden; d.h. wenn start() nicht aufgerufen wird. (An dieser Stelle gibt es keinen native Thread.)

  • Nach dem Aufruf start() und bis der Anruf beendet run(), das Thread Objekt bezeichnet ein lebendes Gewinde. (An dieser Stelle gibt es einen native Thread.)

  • Nach dem run() Anruf beendet, das Thread Objekt bezeichnet einen Faden das nicht mehr existiert. (An dieser Stelle das native Thread, der den Faden verkörpert wurde gelöscht.)

An keiner Stelle ist es Sinn für zwei getrennte Objekte Thread machen den gleichen Thread zu bezeichnen; d.h. derselbe Thread der Ausführung.

Wie soll ich Thread-Objekte für die Gleichheit vergleichen?

Mit == ist der richtige Weg.

Aber equals(Object) ist auch richtig, weil Thread es von Object erbt, wo sie definiert ist die gleiche wie == zu sein.


Auf den Punkt des Stils.

Einige würden argumentieren, dass es stilistisch besser ist, equals zu verwenden. Jedoch gibt es in diesem Kontext, der Thread Javadoc (in der Tat), dass equals und == das gleiche tun. Tatsächlich ist die Referenzgleichheit die einzige Gleichheitssemantik, die für Objekte Thread einen Sinn ergeben würde. Dies ergibt sich aus der Art und Weise, wie der Thread-Lebenszyklus funktioniert, und der Tatsache, dass zwei unterschiedliche Ausführungsstränge intuitiv ausgeführt werden. (Sie könnten konsistent die gleichen Ergebnisse produzieren, aber das ist "emergent" Verhalten ... und beweisen, dass das Verhalten im Allgemeinen ein hartnäckiges Problem ist.)

Auf der anderen Seite ging es bei dieser Frage nicht um Stil. Es ging darum, ob == in diesem Zusammenhang semantisch korrekt ist.

2

Die erste wichtige Sache hier ist: es kann nicht zwei Threads sein, die gleich wären, aber unterschiedliche Referenzen haben.

Also im Wesentlichen: Dies ist einer der seltenen Fälle, in denen die Verwendung der Überprüfung für gleiche Referenzen sinnvoll ist. Insbesondere in einem Fall, in dem es nicht darum geht, eine "beliebig hohe" Anzahl von Thread-Objekten zu vergleichen. Sie nur eine, um sicherzustellen, dass der "aktuelle" Thread (nicht) eine Thread-Referenz ist, die Sie zuvor gespeichert haben.

Natürlich könnte man auch equals(Object) verwenden, um Threads zu vergleichen, und vielleicht wäre das besser, um Leser zu überraschen. Auf der anderen Seite wäre dies eher eine "Stilfrage"; in Bezug auf einen Aspekt, der für 99% des Codes, den Sie in Ihrem täglichen Leben lesen/schreiben, wahrscheinlich nicht sehr häufig ist.

Und, wie TJ Crowder richtig darauf hinweist: Thread.equals(Object) übersetzt in Object.equals(Object), die ... eine einfache Überprüfung auf Referenzgleichheit. Zugrunde liegt der Punkt, dass dies wirklich nur Stil ist. Das trifft zu, bis Leute anfangen würden, ihre eigenen Unterklassen von Thread zu erstellen und eine verschiedene Implementation von equals bereitzustellen.

Schließlich ist die zweite wichtige Sache: zwei Java-Thread-Objekte können nicht die gleichen zugrundeliegenden nativen Threads haben.

+2

In der Tat kommt es auf den Stil an, da 'Thread' aus' Object' 'equals' und [' Object # equals'] erbt (http://docs.oracle.com/javase/8/docs/api) /java/lang/Object.html#equals-java.lang.Object-) tut '=='. –

+0

Das dachte ich mir auch; aber nahm sich nicht die Zeit es aufzuschreiben. Habe jetzt; danke für deinen Beitrag! – GhostCat

+0

Ich würde dann vorschlagen, dass wir alle die Kommentare um diesen ungültigen Befund löschen ;-) – GhostCat

1

Von JSL-17:

Diese Threads unabhängig Code auszuführen, der

Es bedeutet

auf Werten und Objekte Wohnsitz in einem gemeinsam genutzten Hauptspeicher arbeitet, daß jede Instanz des Threads, unabhängig von anderen Ausführung wird Instanzen, obwohl die Daten zwischen ihnen geteilt werden können. Daher können sich zwei Instanzen nicht auf denselben nativen Thread beziehen.

Als allgemeinen Fall sollten Sie equals(Object) für die Überprüfung der Gleichheit bevorzugen. Aber für Thread Gleichheit, können Sie entweder == oder equals(Object) Methode verwenden.

Quellcode von Thread.equals(Object) geerbt von java.lang.Object:

public boolean equals(Object obj) { 
     return (this == obj); 
    } 
+0

Link für JSL-17 funktioniert nicht für mich. – Jabir

+0

@Jabir behoben, danke für's Bemerken. –

+0

Gründe für die Abstimmung nach unten? –

Verwandte Themen