Frage

Von welcher Zeit ich mit Threads in Java verbracht habe, habe ich diese zwei Wege gefunden, Fäden zu schreiben:

Mit implements Runnable:

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

Oder mit extends 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 in diesen zwei Blöcken von Code?

War es hilfreich?

Lösung

Ja: implementiert Runnable die bevorzugte Art und Weise ist, es zu tun, IMO. Sie sind nicht wirklich das Verhalten des Thread spezialisiert. Sie geben es nur etwas zu laufen. Das bedeutet Zusammensetzung ist die philosophisch "reinere" Weg zu gehen.

In praktischen Begriffen, es bedeutet, dass Sie Runnable implementieren können und auch von einer anderen Klasse erweitern.

Andere Tipps

tl; dr: implementiert Runnable ist besser. Allerdings ist der Nachteil ist wichtig

Im Allgemeinen würde ich mit so etwas wie Runnable empfehlen anstatt Thread, weil es Ihnen, Ihre Arbeit nur lose mit Ihrer Wahl der Gleichzeitigkeit gekoppelt halten können. Zum Beispiel, wenn Sie eine Runnable und entscheiden, verwenden später, dass dies in der Tat nicht benötigen sie eigene Thread ist, können Sie nur threadA.run () aufrufen.

Caveat: Um hier, ich dringend die Verwendung von rohen Threads entmutigen. Ich viel lieber die Verwendung von Callables und FutureTasks (aus dem Javadoc-: "A cancellable asynchronen Berechnungs"). Die Integration von Timeouts, richtigen Auslöschung und das Thread-Pooling der modernen Gleichzeitigkeit Unterstützung sind viel nützlicher für mich, als Haufen von rohen Threads.

Follow-up: gibt es eine die javadoc zitieren:

Wenn Sie nicht ein bestimmtes Ergebnis benötigen, sollten Konstruktionen der Form mit:

Future<?> f = new FutureTask<Object>(runnable, null)

Also, wenn wir ihre runnable mit Ihrem threadA ersetzen, erhalten wir wie folgt vor:

new FutureTask<Object>(threadA, null)

Eine weitere Option, die Sie näher an Runnables zu bleiben erlaubt ist ein ThreadPoolExecutor . Sie können die ausführen Verfahren in einem Runnable passieren auszuführen‚ um die gegebene Aufgabe irgendwann in der Zukunft.‘

Wenn Sie versuchen mögen einen Thread-Pool verwendet wird, das Codefragment oben würde etwa wie folgt (mit der Executors.newCachedThreadPool () Factory-Methode):

ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());

Die Moral der Geschichte:

Vererben nur, wenn Sie ein bestimmtes Verhalten außer Kraft setzen möchten.

Oder vielmehr sollte es so gelesen werden:

Vererben weniger, Schnittstelle mehr.

Nun so viele gute Antworten, ich möchte auf diesem mehr hinzuzufügen. Dies wird helfen, zu verstehen, Extending v/s Implementing Thread.
Verlängert bindet zwei Klassendateien sehr eng und kann einige ziemlich schwer verursacht mit Code zu behandeln.

Beiden Ansätze machen die gleiche Arbeit, aber es gibt einige Unterschiede gewesen.
Der häufigste Unterschied ist,

  1. Wenn Sie Thread-Klasse erweitern, nach, dass Sie eine andere Klasse nicht erweitern können, die Sie benötigt. (Wie Sie wissen, Java erlaubt es nicht mehr als eine Klasse erben).
  2. Wenn Sie implementieren Runnable, können Sie Platz für Ihre Klasse speichern andere Klasse in der Zukunft zu erweitern oder jetzt.

jedoch ein signifikanter Unterschied zwischen der Umsetzung Runnable und Faden erstreckt, ist, dass
by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.

Im folgenden Beispiel wird Ihnen helfen, besser zu verstehen,

//Implement Runnable Interface...
 class ImplementsRunnable implements Runnable {

private int counter = 0;

public void run() {
    counter++;
    System.out.println("ImplementsRunnable : Counter : " + counter);
 }
}

//Extend Thread class...
class ExtendsThread extends Thread {

private int counter = 0;

public void run() {
    counter++;
    System.out.println("ExtendsThread : Counter : " + counter);
 }
}

//Use the above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {

public static void main(String args[]) throws Exception {
    // Multiple threads share the same object.
    ImplementsRunnable rc = new ImplementsRunnable();
    Thread t1 = new Thread(rc);
    t1.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    Thread t2 = new Thread(rc);
    t2.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    Thread t3 = new Thread(rc);
    t3.start();

    // Creating new instance for every thread access.
    ExtendsThread tc1 = new ExtendsThread();
    tc1.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    ExtendsThread tc2 = new ExtendsThread();
    tc2.start();
    Thread.sleep(1000); // Waiting for 1 second before starting next thread
    ExtendsThread tc3 = new ExtendsThread();
    tc3.start();
 }
}

Ausgabe des obigen Programms.

ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1

In der Runnable Schnittstelle Ansatz, nur eine Instanz einer Klasse wird erstellt, und es wird von verschiedenen Threads geteilt. So wird der Wert des Zählers für jeden einzelnen Thread Zugriff erhöht.

Während, Thread-Klasse Ansatz, müssen Sie separate Instanz für jeden Thread Zugriff erstellen müssen. Daher unterschiedliche Speicher für alle Klasseninstanzen zugeordnet ist und jeder hat einen separaten Zähler, der Wert bleibt gleich, was bedeutet, dass kein Zuwachs passieren, weil keiner der Objektreferenz gleich ist.

Wenn Runnable benutzen?
Verwenden Sie Runnable-Schnittstelle, wenn Sie die gleichen Ressourcen aus der Gruppe von Threads zugreifen möchten. Vermeiden Sie die Verwendung Klasse Thread hier, weil mehrere Objekte Schöpfung mehr Speicher verbraucht, und es wird eine große Performance-Overhead.

Eine Klasse, die Runnable implementiert ist kein Gewinde und nur eine Klasse. Für ein Runnable ein Thema zu werden, müssen Sie eine Instanz der Thread erstellen und vorbei sich in als Ziel aus.

In den meisten Fällen sollte die Runnable-Schnittstelle verwendet werden, wenn Sie planen, die run() Methode und keine anderen Thread Methoden außer Kraft zu setzen. Dies ist wichtig, weil Klassen nicht unterklassiert werden sollte, es sei denn, der Programmierer auf Änderung oder Verbesserung der grundlegenden Verhalten der Klasse will.

Wenn es notwendig ist, eine übergeordnete Klasse zu erweitern, die Umsetzung der Runnable Schnittstelle besser geeignet ist, um die Thread-Klasse als verwenden. Weil wir eine andere Klasse erweitern können, während Runnable-Schnittstelle implementiert, um einen Thread zu machen.

Ich hoffe, dass dies dazu beitragen wird!

Eine Sache, die ich bin überrascht wurde noch nicht erwähnt ist, dass Runnable Implementierung macht die Klasse flexibler.

Wenn Sie Thread erweitern dann die Aktion, die Sie tun, wird immer in einem Thread sein. Wenn Sie jedoch implementieren Runnable muss es nicht sein. Sie können es in einem Thread ausgeführt, oder es zu einer Art Testamentsvollstrecker Dienstes übergeben, oder es nur als eine Aufgabe in einer einzigen Thread-Anwendung übergeben um (vielleicht zu einem späteren Zeitpunkt ausgeführt werden, aber im selben Thread). Die Optionen sind viel offener, wenn Sie nur Runnable als verwenden, wenn Sie sich binden an Thread.

Wenn Sie implementiert wollen oder sich andere Klasse dann Runnable Schnittstelle ist am meisten bevorzugt, sonst, wenn Sie keine andere Klasse erweitern möchten oder implementieren dann Thread Klasse bevorzugt.

Der häufigste Unterschied ist,

eingeben Bild Beschreibung hier

Wenn Sie Klasse extends Thread, nach, dass Sie eine andere Klasse nicht erweitern können, die Sie benötigt. (Wie Sie wissen, Java erlaubt es nicht mehr als eine Klasse erben).

Wenn Sie implements Runnable, Sie Platz für Ihre Klasse speichern können jede andere Klasse in der Zukunft zu erweitern oder jetzt.

  • Java unterstützt nicht mehr Erbschaften, was bedeutet, dass Sie nur eine Klasse in Java erweitern können so, wenn Sie Thread-Klasse erweitern Sie Ihre Chance verloren und kann eine andere Klasse in Java nicht erweitern oder erben.

  • in der objektorientierten Programmierung, eine Klasse, die sie im allgemeinen bedeutet, neue Funktionalität hinzuzufügen, und die Änderung oder Verhaltensweisen zu verbessern. Wenn wir keine Änderungen am Thema machen dann Runnable-Schnittstelle verwenden, statt.

  • Runnable-Schnittstelle stellt eine Aufgabe, die durch entweder schlicht Thema oder Testamentsvollstrecker oder andere Mittel ausgeführt werden kann. so logische Trennung von Aufgaben als Runnable als Thema ist eine gute Design-Entscheidung.

  • Die Trennung Aufgabe als Runnable bedeutet, dass wir die Aufgabe wiederverwenden können und hat auch die Freiheit, aus verschiedenen Mitteln auszuführen. da Sie nicht einen Thread neu starten kann, sobald es abgeschlossen ist. wieder Runnable vs Thema für Aufgabe, Runnable ist Sieger.

  • Java-Designer erkennt dies und deshalb Testamentsvollstrecker Runnable als Aufgabe übernehmen und sie haben Worker-Thread, die jene Aufgabe ausführt.

  • Vererben alle Themen-Methoden sind zusätzlicher Aufwand nur eine Aufgabe für die Darstellung, die leicht mit Runnable getan werden kann.

Mit freundlicher Genehmigung von javarevisited.blogspot.com

Dies waren einige der bemerkenswerten Unterschiede zwischen Thema und Runnable in Java. Wenn Sie weitere Unterschiede auf Thread vs Runnable wissen, als Sie es bitte über Kommentare teilen. Ich persönlich benutze Runnable über Themen für dieses Szenario und empfiehlt Runnable oder aufrufbare Schnittstelle auf Basis Ihrer Anforderung zu verwenden.

jedoch der signifikante Unterschied ist.

Wenn Sie Klasse extends Thread, jede Ihres Faden schafft ein einzigartiges Objekt und assoziiert mit ihm. Wenn Sie implements Runnable, teilt es das gleiche Objekt mehrere Threads.

Eigentlich ist es nicht klug, Runnable und Thread miteinander zu vergleichen.

Diese beide haben eine Abhängigkeit und Beziehung in Multi-Threading wie Wheel and Engine Beziehung von Kraftfahrzeugen.

Ich würde sagen, es gibt nur einen Weg, für Multi-Threading mit zwei Schritten ist. Lassen Sie mich meinen Punkt machen.

Runnable:
Wenn interface Runnable Umsetzung bedeutet, dass Sie etwas zu schaffen, die in einem anderen Thread run able wird. Jetzt etwas zu schaffen, die in einem Gewinde (runnable in einem Thread) ausgeführt werden können, bedeutet nicht, einen Thread zu schaffen.
So ist die Klasse MyRunnable ist nichts anderes als eine gewöhnliche Klasse mit einem void run Verfahren. Und es ist Objekte werden einige gewöhnliche Objekte mit nur einer Methode run sein, die normalerweise ausgeführt werden, wenn sie aufgerufen. (Es sei denn, wir passieren das Objekt in einem Thread).

Thema:
class Thread, ich würde sagen, eine ganz besondere Klasse mit der Fähigkeit, einen neuen Thread zu starten, die eigentlich Multithreading durch seine start() Methode ermöglicht.

Warum nicht klug vergleichen?
Denn wir brauchen sie beide für Multi-Threading.

Für Multi-Threading wir brauchen zwei Dinge:

  • Etwas, das in einem Thread (Runnable) laufen kann.
  • Etwas, das einen neuen Thread starten (Thread).

So technisch und theoretisch beide notwendig ist, einen Thread zu starten, wird ein run und man wird machen es laufen (wie Wheel and Engine von Kraftfahrzeug).

Das ist, warum Sie nicht einen Thread mit MyRunnable beginnen können Sie es auf eine Instanz von Thread übergeben müssen.

Aber ist es möglich, einen Thread nur class Thread verwenden, da Klasse Thread implementiert Runnable so wissen wir alle Thread auch eine Runnable innen zu erstellen und auszuführen.

Schließlich Thread und Runnable sind aufeinander abgestimmt werden für Multithreading nicht Wettbewerber oder Ersatz.

Sie sollten Runnable implementieren, aber wenn Sie auf Java 5 oder höher ausgeführt wird, sollten Sie es nicht mit new Thread beginnen, aber ein ExecutorService statt. Weitere Einzelheiten finden Sie unter:. Wie in Java einfaches Einfädeln implementieren

Ich bin kein Experte, aber ich kann aus einem Grund denken Runnable zu implementieren, anstatt Gewinde erweitern. Java unterstützt nur einfache Vererbung, so dass Sie nur eine Klasse erweitern

Edit: Das ursprünglich gesagt, „Implementierung einer Schnittstelle weniger Ressourcen erfordert.“ wie gut, aber Sie müssen eine neue Thread-Instanz oder so erstellen, so dass dies falsch war.

Ich würde sagen, dass es ein dritte Weg ist:

public class Something {

    public void justAnotherMethod() { ... }

}

new Thread(new Runnable() {
   public void run() {
    instanceOfSomething.justAnotherMethod();
   }
}).start();

Vielleicht ist das ein bisschen von meiner letzten starken Nutzung von Javascript beeinflusst und Actionscript 3, aber auf diese Weise Ihre Klasse braucht nicht eine ziemlich vage Schnittstelle wie Runnable zu implementieren.

Mit der Veröffentlichung von Java 8, gibt es jetzt eine dritte Option.

Runnable ist ein funktionale Schnittstelle , die bedeutet, dass mit Lambda-Ausdrücke oder Verfahren Referenzen Instanzen davon erstellt werden.

kann Ihr Beispiel ersetzt werden:

new Thread(() -> { /* Code here */ }).start()

oder wenn Sie wollen eine ExecutorService und ein Verfahren Referenz verwenden:

executor.execute(runner::run)

Diese sind nicht nur viel kürzer als die Beispiele, aber auch mit vielen der Vorteile kommen in anderen Antworten erwähnt Runnable über Thread, wie einzelne Verantwortung der Verwendung und Zusammensetzung verwendet wird, weil Sie nicht den Faden Verhalten spezialisiert. Auf diese Weise vermeidet auch eine zusätzliche Klasse zu schaffen, wenn alles, was Sie brauchen, ist ein Runnable ist, wie Sie in Ihren Beispielen tun.

Instanziieren eine Schnittstelle eine sauberere Trennung zwischen Code und der Implementierung von Threads gibt, so würde ich es vorziehen, Runnable in diesem Fall zu implementieren.

Jeder scheint hier zu denken, dass Runnable Umsetzung der Weg zu gehen, und ich weiß nicht wirklich mit ihnen nicht einverstanden ist, aber es ist auch ein Fall für Thema meiner Meinung nach erstreckt, in der Tat haben Sie eine Art es in Ihrem Code demonstriert.

Wenn Sie Runnable implementieren dann die Klasse, die implementiert Runnable keine Kontrolle über den Thread-Namen hat, ist es der anruf Code, der den Thread-Namen festlegen können, etwa so:

new Thread(myRunnable,"WhateverNameiFeelLike");

, aber wenn Sie verlängern Thema dann bekommen Sie diese selbst innerhalb der Klasse zu verwalten (wie in Ihrem Beispiel nennen Sie den Faden ‚ThreadB‘). In diesem Fall Sie:

A) geben könnte ihm einen nützlichen Namen Zwecke für die Fehlersuche

B) zwingt, dass dieser Name für alle Instanzen dieser Klasse verwendet werden (es sei denn, Sie ignorieren die Tatsache, dass es ein Thread ist und damit die oben tun, als ob es ein lauffähiges, aber wir sprechen über Konvention hier in jedem Fall so kann diese Möglichkeit ignoriert ich fühle).

Sie können sogar zum Beispiel einen Stack-Trace seiner Schöpfung nehmen und als Thread-Namen verwenden. Dies mag seltsam, aber je nachdem, wie Ihr Code strukturiert ist es für Debug-Zwecke sehr nützlich sein kann.

Dies mag wie eine Kleinigkeit erscheinen, aber wo Sie haben eine sehr komplexe Anwendung mit vielen Fäden und ganz plötzlich Dinge ‚aufgehört hat‘ (entweder aus Gründen der Sackgasse oder möglicherweise aufgrund eines Fehlers in einem Netzwerk-Protokoll, das wäre weniger offensichtlich - oder andere Endlos Gründe) dann einen Stack Dump von Java bekommen, wo alle Fäden ‚Gewinde-1‘, ‚Thema-2‘, ‚Gewinde-3‘ ist nicht immer sehr nützlich (es hängt davon ab, wie genannt werden Ihre Themen sind so strukturiert, und ob man sinnvollerweise sagen kann, welche die gerade durch ihren Stack-Trace ist -. nicht immer möglich, wenn Sie Gruppen von mehreren Threads alle den gleichen Code ausgeführt wird)

verwenden

Nachdem das nun gesagt, dass Sie könnte natürlich auch nicht die oben in allgemeiner Weise durch eine Verlängerung der Thread-Klasse zu schaffen, die ihren Namen einem Stack-Trace setzt seiner Entstehung Call- und verwenden dann, dass mit Ihrer Runnable Implementierungen anstelle der Standard Java-Thread-Klasse (siehe unten), aber zusätzlich zu dem Stack-Trace es könnte mehr kontextspezifische Informationen, die zum Beispiel für das Debuggen (ein Verweis auf eine von vielen Warteschlangen oder Buchsen es könnte Verarbeitung im Thread-Namen nützlich wäre, in dem Fall, dass Sie könnte es vorziehen, für diesen Fall Thema speziell zu erweitern, so dass Sie die Compiler-Kraft, die Sie (Ihre Bibliotheken oder andere verwenden) haben in bestimmten Informationen zu übergeben (zB die Warteschlange / Buchse in Frage) für den Einsatz im Namen).

Hier ist ein Beispiel des allgemeinen Thread mit dem Aufruf-Stack-Trace wie sein Name:

public class DebuggableThread extends Thread {
    private static String getStackTrace(String name) {
        Throwable t= new Throwable("DebuggableThread-"+name);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(os);
        t.printStackTrace(ps);
        return os.toString();
    }

    public DebuggableThread(String name) {
        super(getStackTrace(name));
    }

    public static void main(String[] args) throws Exception {
        System.out.println(new Thread());
        System.out.println(new DebuggableThread("MainTest"));
    }
}

und hier ist ein Beispiel für die Ausgabe, die beiden Namen zu vergleichen:

Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
    at DebuggableThread.getStackTrace(DebuggableThread.java:6)
    at DebuggableThread.<init>(DebuggableThread.java:14)
    at DebuggableThread.main(DebuggableThread.java:19)
,5,main]

Runnable weil:

  • Leaves mehr Flexibilität für die Runnable Implementierung zu erweitern Eine andere Klasse
  • Trennt den Code aus Ausführung
  • Damit können Sie führen Sie Ihre runnable von einem Thread-Pool, die Ereignis-Gewinde, oder in irgendeiner anderen Weise in die Zukunft.

Auch wenn Sie jetzt irgendetwas davon nicht benötigen, können Sie in der Zukunft. Da es keinen Nutzen für die übergeordnete Thema ist, Runnable ist eine bessere Lösung.

Da dies ein sehr beliebtes Thema ist und die guten Antworten sind überall verstreut und behandelten in großer Tiefe, fühlte ich es gerechtfertigt ist, die guten Antworten von den andere in eine prägnante Form zusammenzustellen, so Neulinge haben einen einfachen Überblick upfront:

  1. Sie erweitern in der Regel eine Klasse hinzuzufügen, oder Funktionalitäten zu ändern. Also, , wenn Sie nicht wollen, Überschreiben jedes Thread Verhalten , dann Runnable verwenden.

  2. Im gleichen Licht, , wenn Sie brauchen nicht inherit Thread Methoden, Sie ohne das Overhead tun durch Runnable verwendet wird.

  3. Single Vererbung . Wenn Sie Themen erweitern Sie können nicht von einer anderen Klasse erweitern, so dass, wenn das ist, was Sie tun müssen, müssen Sie Runnable verwenden

  4. Es ist ein gutes Design zu separater Domäne Logik von technischen Mitteln, in diesem Sinne ist es besser, eine Runnable Aufgabe zu haben, Isolieren Aufgabe von Läufer .

  5. Sie können execute die gleiche Runnable Objekt mehrere Male , ein Thread-Objekt kann jedoch nur einmal gestartet werden. (Vielleicht ist der Grund, warum Testamentsvollstrecker Runnables akzeptieren, aber nicht Threads).

  6. Wenn Sie Ihre Aufgabe als Runnable entwickeln, haben Sie alle Flexibilität, wie es jetzt nutzen und in der Zukunft . Sie können es gleichzeitig über Testamentsvollstrecker, sondern auch über Themen haben laufen. Und man konnte auch noch gebrauchen / nennen es nicht gleichzeitig im selben Thread wie jede andere gewöhnliche Art / Objekt.

  7. Dies macht es auch leichter zu getrennt Task-Logik und Gleichzeitigkeit Aspekte in Unit-Tests .

  8. Wenn Sie in dieser Frage interessiert sind, könnten Sie auch in der Unterschied zwischen Callable und Runnable .

Der Unterschied zwischen Thema Erweiterung und Implementierung von Runnable sind:

 image description hier

Dies ist in Oracle definieren und einen Thread Tutorial starten:

  

Welche dieser Idiome sollten Sie verwenden? Das erste Idiom, die eine beschäftigt   Ausführbare Objekt, ist allgemeiner, weil das Runnable-Objekt kann   Unterklasse eine andere Klasse als Thread. Das zweite Idiom ist einfacher zu bedienen   in einfachen Anwendungen, sondern wird durch die Tatsache, dass Ihre Aufgabe beschränkt   Klasse muss ein Nachkomme Thema sein. Diese Lektion konzentriert sich auf die erste   Ansatz, der die Runnable Aufgabe aus dem Thread-Objekt trennt   dass führt die Aufgabe. Nicht nur ist dieser Ansatz flexibler, aber   es ist auf dem High-Level-APIs Thread-Management abgedeckt   später.

Mit anderen Worten, Runnable Umsetzung in Szenarien arbeiten, wo Ihre Klasse erweitert eine Klasse andere als Thread. Java unterstützt keine Mehrfachvererbung. Auch Thread Verlängerung ist nicht möglich, wenn einige der High-Level-Thread-Management-APIs. Das einzige Szenario, in dem Thread erstreckt vorzuziehen ist, ist in einer kleinen Anwendung, die Aktualisierungen in Zukunft nicht unterliegen. Es ist fast immer besser umzusetzen Runnable wie es flexibler als Ihr Projekt wächst ist. Eine Designänderung wird keinen großen Einfluss haben, wie Sie viele Schnittstellen in Java implementieren können, aber nur eine Klasse erweitern.

Wenn ich nicht falsch bin, es ist mehr oder weniger ähnlich wie

Was ist der Unterschied zwischen eine Schnittstelle und abstrakte Klasse?

erstreckt sich gründet " ein " Relation & Schnittstelle bietet " Hat ein " -Fähigkeit.

Bevorzugen implementiert Runnable :

  1. Wenn Sie müssen nicht Thread-Klasse erweitern und Themen-API Standardimplementierung
  2. ändern
  3. Wenn Sie ein Feuer ausführen und vergessen Befehl
  4. Wenn Sie bereits eine andere Klasse erweitert

Bevorzugen " erstreckt Thema ":

  1. Wenn Sie eines dieser Thema außer Kraft zu setzen haben Methoden wie in der oracle-Dokumentation Seite
  2. aufgelistet

Im Allgemeinen müssen Sie nicht Thema Verhalten außer Kraft zu setzen. So implementiert Runnable für die meisten der Zeit bevorzugt.

Auf einer anderen Note, mit Hilfe modernster ExecutorService oder ThreadPoolExecutorService API mehr Flexibilität und Kontrolle bietet.

Haben Sie einen Blick auf diese SE Frage:

ExecutorService vs Gelegenheits Thema Spawner

Die einfachste Erklärung wäre durch Runnable setzen wir das gleiche Objekt mehrere Threads und jeder Thread teilt die gleichen Objektzustände und Verhalten zuweisen können.

Angenommen, es gibt zwei Themen, thread1 stellt eine ganze Zahl in einem Array und thread2 Zahlen aus dem Array nimmt, wenn das Array voll ist. Beachten Sie, dass, um für thread2 arbeiten, um es den Zustand des Array wissen muss, ob thread1 hat es gefüllt oder nicht.

Runnable Implementierung können Sie diese Flexibilität haben, um das Objekt zu teilen, während extends Thread macht Sie für jedes Threads neue Objekte erstellen daher jede Aktualisierung, die von thread1 erfolgt verloren Thread2.

Die Trennung der Thread-Klasse von der Runnable Implementierung vermeidet auch mögliche Synchronisationsprobleme zwischen dem Faden und dem Run () -Methode. Eine separate Runnable ergibt in der Regel eine größere Flexibilität in der Art und Weise, dass runnable Code verwiesen wird und ausgeführt wird.

Das ist der S von SOLID : Einzelne Verantwortung.

A Gewinde verkörpert den Lauf Kontext (wie in dem Ausführungskontext: Stapelrahmen, Thread-ID, etc.) der asynchronen Ausführung von ein Stück Code. Das Stück Code sollte idealerweise die gleiche Implementierung sein, ob Synchron oder asynchron .

Wenn Sie sie zusammen in einer Implementierung bündeln, geben Sie das resultierende Objekt zwei nicht verwandt Ursachen der Veränderung:

  1. Thread-Verarbeitung in der Anwendung (dh. Abfragen und ändern den Ausführungskontext)
  2. Algorithmus durch das Stück Code (der runnable Teil)
  3. implementiert

Wenn die Sprache verwenden Sie partielle Klassen oder Mehrfachvererbung unterstützt, dann können Sie jede Ursache in seiner eigenen Superklasse abzusondern, aber es läuft darauf hinaus, die gleichen sich wie die beiden Objekte zu komponieren, da ihre Feature-Sets nicht überlappen. Das ist für die Theorie.

In der Praxis allgemein gesprochen, ein Programm braucht nicht mehr Komplexität als nötig zu tragen. Wenn Sie einen Thread arbeitet an einer bestimmten Aufgabe haben, ohne jemals diese Aufgabe zu ändern, gibt es wahrscheinlich keinen Sinn macht, die Aufgaben separate Klassen, und Ihr Code bleibt einfacher.

Im Rahmen von Java , da die Anlage ist schon da , ist es wahrscheinlich einfacher, direkt mit Stand-alone-Runnable Klassen zu starten, und die Instanzen passieren Thread ( oder Executor) Instanzen. Sobald verwendet zu diesem Muster ist es nicht schwieriger zu verwenden (oder sogar lesen) als der einfache ausführbare Thread Fall.

Ein Grund, warum Sie eine Schnittstelle wollen lieber implementieren als eine Basisklasse zu erweitern ist, dass Sie bereits eine andere Klasse erweitern. Sie können nur eine Klasse erweitern, aber Sie können eine beliebige Anzahl von Schnittstellen implementieren.

Wenn Sie Thema erweitern, sind Sie im Grunde Ihre Logik zu verhindern, indem jeder anderen Thread ausgeführt werden, als ‚this‘. Wenn Sie nur einige Thread Ihre Logik auszuführen, ist es besser, nur Runnable zu implementieren.

Wenn Sie runnable verwenden, können Sie den Raum speichern zu einem Ihrer anderen Klasse zu erweitern.

Können wir wieder besuchen den Grund Grund, warum wir unsere Klasse als Thread verhalten wollten? Es gibt keinen Grund überhaupt, wir wollten nur eine Aufgabe auszuführen, höchstwahrscheinlich in einem asynchronen Modus, was bedeutet genau, dass die Ausführung der Aufgabe unseres Haupt-Thread verzweigen muß und der Haupt-Thread, wenn beendet früh kann oder nicht warten kann für den abgezweigten Pfad (Aufgabe).

Wenn dies der ganze Zweck ist, dann wo ich die Notwendigkeit eines speziellen Themas zu sehen. Dies kann durch Aufnehmen einen RAW-Thread aus dem Threadpool-System erreicht werden, und die Zuweisung es unsere Aufgabe (kann eine Instanz von unserer Klasse sein), und das ist es.

Lassen Sie uns also die OOPs Konzept gehorchen und eine Klasse des Typs schreiben wir brauchen. Es gibt viele Möglichkeiten, Dinge zu tun, ist es in der richtigen Art und Weise Dinge zu tun.

Wir brauchen eine Aufgabe, so eine Aufgabendefinition schreiben, die auf einem Thread ausgeführt werden kann. So Runnable verwenden.

Denken Sie immer daran implements ist speziell verwendet, um ein Verhalten zu verleihen, und extends verwendet wird, eine Funktion / Eigenschaft zu verleihen.

Wir wollen nicht die Eigenschaft des Threads, anstatt wollen wir unsere Klasse als eine Aufgabe verhalten, die ausgeführt werden können.

Ja, Wenn Sie ThreadA Anruf rufen, dann müssen nicht den Start-Methode aufrufen und run-Methode ist nach Aufruf nur die ThreadA Klasse Anruf. Aber wenn der Anruf ThreadB verwenden, dann müssen notwendige Start Thread für Call run-Methode. Wenn Sie weitere Hilfe haben, antworten Sie mir.

Ich finde es sehr nützlich ist Runnable zu verwenden, um all die genannten Gründe, aber manchmal mag ich Thema erweitern, damit ich meine eigenen Thread zu stoppen Methode erstellen und es direkt auf dem Thread nenne ich geschaffen haben.

Java unterstützt nicht mehrere inheritence so, wenn Sie Thread-Klasse erstreckt sich dann keine andere Klasse erweitert werden.

Zum Beispiel: Wenn Sie ein Applet erstellen dann reicht es muss Applet-Klasse so hier die einzige Möglichkeit Thread zu erstellen durch Runnable-Schnittstelle implementiert

Runnable ist eine Schnittstelle, während Thread eine Klasse, die diese Schnittstelle implementiert. Aus gestalterischen Sicht sollte es eine klare Trennung zwischen dem, wie eine Aufgabe definiert ist, und zwischen dem, wie er ausgeführt wird. Erstere ist die Verantwortung eines Runnalbe Implementierung, und letztere ist Aufgabe der Thread Klasse. In den meisten Fällen der Umsetzung Runnable ist der richtige Weg zu folgen.

Der Unterschied zwischen Thema und runnable .Wenn wir Gewinde mit Thread-Klasse dann Anzahl der Gewinde gleich Anzahl von Objekt schaffen wir geschaffen. Wenn wir Thread erstellen, indem Sie den runnable Schnittstelle implementieren, dann können wir einzelnes Objekt verwenden, um mehr für die Erstellung von thread.So einzelnes Objekt wird durch mehr gemeinsam genutzten Thread.So es wenige Speicher braucht

Also je nach Anforderung, wenn unsere Daten nicht sensitiv sind. So Es kann zwischen mehreren Themen geteilt werden wir Runnable-Schnittstelle verwendet werden.

Hinzufügen meine zwei Cent hier - Immer wenn möglich Gebrauch implements Runnable. Im Folgenden sind zwei Einschränkungen auf, warum sollten Sie nicht verwenden extends Threads

  1. Im Idealfall sollten Sie nie die Thread-Klasse erweitern; die Thread Klasse sollte final gemacht werden. Zumindest seine Methoden wie thread.getId(). Siehe dieser Diskussion für einen Bug zu erstrecken Threads verwendet.

  2. Diejenigen, die Rätsel zu lösen, wie eine andere Nebenwirkung der Verlängerung Thema sehen. Der Code unten wird nicht erreichbar Code drucken, wenn niemand sie Kenntnis zu setzen.

Bitte finden Sie unter http://pastebin.com/BjKNNs2G .

public class WaitPuzzle {

    public static void main(String[] args) throws InterruptedException {
        DoNothing doNothing = new DoNothing();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        new WaitForever(doNothing).start();
        Thread.sleep(100);
        doNothing.start();
        while(true) {
            Thread.sleep(10);
        }
    }


    static class WaitForever extends  Thread {

        private DoNothing doNothing;

        public WaitForever(DoNothing doNothing) {
            this.doNothing =  doNothing;
        }

        @Override
        public void run() {
            synchronized (doNothing) {
                try {
                    doNothing.wait(); // will wait forever here as nobody notifies here
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Unreachable Code");
            }
        }
    }

    static class DoNothing extends Thread {

        @Override
        public void run() {
            System.out.println("Do Nothing ");
        }
    } 
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top