2355 Stimmen

"implementiert Runnable" vs. "erweitert Thread" in Java

Nach der Zeit, die ich mit Threads in Java Ich habe diese beiden Möglichkeiten gefunden, Themen zu schreiben:

Mit implementiert Runnable :

public class MyRunnable implements Runnable {
    public void run() {
        //Code
    }
}
//Started with a "new Thread(new MyRunnable()).start()" call

Oder, mit erweitert Thread :

public class MyThread extends Thread {
    public MyThread() {
        super("MyThread");
    }
    public void run() {
        //Code
    }
}
//Started with a "new MyThread().start()" call

Gibt es einen signifikanten Unterschied zwischen diesen beiden Codeblöcken?

66 Stimmen

Vielen Dank für diese Frage, die Antworten haben eine Menge Missverständnisse, die ich hatte, aufgeklärt. Ich schaute in den richtigen Weg, um Java-Threads zu tun, bevor SO existierte und es gab eine Menge von Fehlinformationen / veraltete Informationen da draußen.

5 Stimmen

Gibt es einen Grund, warum Sie den Thread ( aber ich empfehle es nicht ), können Sie präventiv mit interrupt() . Auch hier handelt es sich um eine Idee, die im richtigen Fall nützlich sein könnte, aber ich empfehle sie nicht.

0 Stimmen

Bitte lesen Sie auch die Antwort, die sehr gut erklärt ist: stackoverflow.com/q/5562720/285594

12voto

Jörg Punkte 2314

Da dies ein sehr beliebtes Thema ist und die guten Antworten überall verstreut sind und sehr ausführlich behandelt werden, hielt ich es für vertretbar, die guten Antworten der anderen in einer übersichtlicheren Form zusammenzustellen, damit Neulinge von vornherein einen leichten Überblick haben:

  1. Normalerweise erweitert man eine Klasse, um Funktionen hinzuzufügen oder zu ändern. So, wenn Sie nicht wollen a überschreiben. cualquier Verhalten bei Gewinden und verwenden Sie dann Runnable.

  2. In demselben Licht, wenn Sie nicht brauchen a erben Thread-Methoden, können Sie auf diese Overhead durch die Verwendung von Runnable.

  3. Einzelvererbung : Wenn Sie Thread erweitern, können Sie nicht von einer anderen Klasse erweitern, wenn Sie das also tun wollen, müssen Sie Runnable verwenden.

  4. Es ist ein gutes Design, die Domänenlogik von den technischen Mitteln zu trennen, in diesem Sinne ist es besser, einen Runnable Task zu haben Isolierung Ihr Aufgabe von Ihr Läufer .

  5. Sie können ausführen. das gleiche Runnable Objekt mehrere Male Ein Thread-Objekt kann jedoch nur einmal gestartet werden. (Vielleicht der Grund, warum Executors zwar Runnables, aber keine Threads akzeptieren).

  6. Wenn Sie Ihre Aufgabe als Runnable entwickeln, haben Sie die ganze Flexibilität, wie man sie jetzt und in Zukunft nutzen kann . Sie können es gleichzeitig über Executors, aber auch über Threads laufen lassen. Und Sie könnten es auch nicht-gleichzeitig innerhalb desselben Threads verwenden/aufrufen, wie jeden anderen gewöhnlichen Typ/Objekt.

  7. Dies macht es auch einfacher, die getrennt Aufgabenlogik und Gleichzeitigkeit Aspekte in Ihr Einheitstests .

  8. Wenn Sie sich für diese Frage interessieren, sind Sie vielleicht auch an der Unterschied zwischen Callable und Runnable .

0 Stimmen

@Pino Ja, Thread selbst ist auch ein Runnable. Wenn man ihn jedoch erweitert, um ihn einfach als Runnable zu verwenden, was ist dann der Sinn? Warum nicht einfach eine einfache Runnable ohne den ganzen Ballast verwenden. Ich würde also argumentieren, dass, wenn Sie Thread erweitern, würden Sie es auch ausführen, indem Sie seine Start-Methode, die nur einmal verwendet werden kann. Das ist der Punkt, den Nidhish-Krishnan in seiner Antwort ansprechen wollte. Beachten Sie, dass meine Antwort nur eine Zusammenstellung oder kurze Zusammenfassung anderer Antworten hier ist.

9voto

Shababb Karim Punkte 3468

Die einfachste Erklärung wäre die Implementierung von Runnable können wir dasselbe Objekt mehreren Threads zuweisen und jeder Thread die gleichen Objektzustände und das gleiche Verhalten.

Nehmen wir zum Beispiel an, es gibt zwei Threads, Gewinde1 setzt eine ganze Zahl in ein Array und Thema2 nimmt ganze Zahlen aus dem Array, wenn das Array voll ist. Beachten Sie, dass, um für Thema2 zu arbeiten, muss es den Zustand des Arrays kennen, ob Gewinde1 aufgefüllt hat oder nicht.

Umsetzung von Runnable lässt Ihnen diese Flexibilität, das Objekt zu teilen, während extends Thread führt dazu, dass für jeden Thread neue Objekte erstellt werden müssen, so dass jede Aktualisierung, die von Thread1 vorgenommen wird, für Thread2 verloren geht.

9voto

Sionnach733 Punkte 4586

Dies wird in Oracles Definieren und Starten eines Themas Tutorium:

Welche der folgenden Redewendungen sollten Sie verwenden? Das erste Idiom, bei dem ein Runnable-Objekt verwendet, ist allgemeiner, denn das Runnable-Objekt kann Unterklasse einer anderen Klasse als Thread sein kann. Das zweite Idiom ist einfacher zu verwenden in einfachen Anwendungen zu verwenden, ist aber dadurch eingeschränkt, dass Ihre Task Klasse ein Abkömmling von Thread sein muss. Diese Lektion konzentriert sich auf den ersten Ansatz, der die Runnable-Aufgabe von dem Thread-Objekt trennt trennt, das die Aufgabe ausführt. Dieser Ansatz ist nicht nur flexibler, sondern sondern ist auch für die später behandelten High-Level-Thread-Management-APIs später behandelt werden.

Mit anderen Worten, die Umsetzung Runnable funktioniert in Szenarien, in denen Ihre Klasse eine andere Klasse als Thread . Java unterstützt keine Mehrfachvererbung. Auch die Erweiterung von Thread ist nicht möglich, wenn einige der High-Level-Thread-Management-APIs verwendet werden. Das einzige Szenario, in dem die Erweiterung Thread ist in einer kleinen Anwendung vorzuziehen, die in Zukunft nicht mehr aktualisiert werden soll. Es ist fast immer besser, die Runnable da sie flexibler ist, wenn Ihr Projekt wächst. Eine Designänderung wird keine großen Auswirkungen haben, da Sie in Java viele Schnittstellen implementieren, aber nur eine Klasse erweitern können.

6voto

dharam Punkte 7584

Können wir uns noch einmal den Grund ansehen, warum wir wollten, dass sich unsere Klasse wie eine Thread ? Es gibt überhaupt keinen Grund, wir wollten nur eine Aufgabe ausführen, höchstwahrscheinlich in einem asynchronen Modus, was genau bedeutet, dass die Ausführung der Aufgabe von unserem Haupt-Thread verzweigen muss und der Haupt-Thread, wenn er früh endet, auf den verzweigten Pfad (Aufgabe) warten kann oder nicht.

Wenn das der Sinn und Zweck ist, wo sehe ich dann die Notwendigkeit eines speziellen Threads. Dies kann erreicht werden, indem man einen RAW-Thread aus dem Thread-Pool des Systems aufnimmt und ihm unsere Aufgabe zuweist (kann eine Instanz unserer Klasse sein) und das war's.

Halten wir uns also an das OOP-Konzept und schreiben wir eine Klasse des von uns benötigten Typs. Es gibt viele Möglichkeiten, Dinge zu tun, aber es kommt darauf an, es auf die richtige Weise zu tun.

Wir brauchen eine Aufgabe, also schreiben wir eine Aufgabendefinition, die auf einem Thread ausgeführt werden kann. Verwenden Sie also Runnable.

Immer daran denken implements wird speziell verwendet, um ein Verhalten zu vermitteln und extends wird verwendet, um eine Funktion/Eigenschaft zu vermitteln.

Wir wollen nicht die Eigenschaft des Threads, sondern wir wollen, dass sich unsere Klasse wie eine Aufgabe verhält, die ausgeführt werden kann.

6voto

Ravindra babu Punkte 45577

Wenn ich mich nicht irre, ist es mehr oder weniger ähnlich wie

Was ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?

erweitert stellt fest " Ist A " Beziehung & Schnittstelle bietet " Hat eine Fähigkeit".

Bevorzugt implementiert Runnable :

  1. Wenn Sie die Thread-Klasse nicht erweitern und die Standardimplementierung der Thread-API nicht ändern müssen
  2. Wenn Sie einen Feuerbefehl ausführen und vergessen
  3. Wenn Sie bereits eine andere Klasse erweitern

Bevorzugen " erweitert das Gewinde " :

  1. Wenn Sie eine dieser Optionen außer Kraft setzen müssen Thema Methoden wie in der Oracle-Dokumentationsseite aufgeführt

Im Allgemeinen müssen Sie das Verhalten von Threads nicht außer Kraft setzen. Also implementiert Runnable wird in den meisten Fällen bevorzugt.

Eine andere Sache ist die Verwendung von fortgeschrittenen ExecutorService o ThreadPoolExecutorService API bietet mehr Flexibilität und Kontrolle.

Werfen Sie einen Blick auf diese SE-Frage:

ExecutorService vs. Casual Thread Spawner

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X