Domanda

Da quanto tempo ho trascorso con i thread in Java, ho trovato questi due modi per scrivere thread:

Con implements Runnable:

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

Oppure, con extends Thread:

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

C'è qualche differenza significativa in questi due blocchi di codice?

È stato utile?

Soluzione

Si: implementa Runnable è il modo migliore per farlo, IMO. Non sei davvero specializzata comportamento del thread. Stai solo dando qualcosa da eseguire. Ciò significa composizione è il filosoficamente modo "più pura" per andare.

In termini pratici , significa che è possibile implementare ed estendere Runnable da un'altra classe pure.

Altri suggerimenti

tl; dr: implementa Runnable è meglio. Tuttavia, l'avvertimento è importante

In generale, mi consiglia di utilizzare qualcosa come Runnable piuttosto che Thread perché permette di mantenere il vostro lavoro solo vagamente accoppiato con la vostra scelta di concorrenza. Ad esempio, se si utilizza un Runnable e decidere in seguito che questo fatto non richiedono di essa la propria Thread, si può chiamare threadA.run ().

Caveat: Da queste parti, ne sconsiglio vivamente l'utilizzo di fili greggi. Preferisco di gran lunga l'uso di callable e FutureTasks (Dalla javadoc: "A cancellable calcolo asincrono"). L'integrazione di timeout, la corretta cancellazione e la messa in comune filo del moderno supporto concorrenza sono tutti molto più utile per me più di mucchi di Fili prime.

Follow-up: non è un costruttore FutureTask che permette di utilizzare Runnables (se è questo che si sta più comodi con) e ancora ottenere il beneficio dei moderni strumenti di concorrenza . Per citare il javadoc :

Se non avete bisogno di un risultato particolare, è possibile utilizzare le costruzioni di forma:

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

Quindi, se si sostituisce la loro runnable con il threadA, otteniamo la seguente:

new FutureTask<Object>(threadA, null)

Un'altra opzione che ti permette di rimanere più vicino a Runnables è un ThreadPoolExecutor . È possibile utilizzare il execute metodo per passare un Runnable per eseguire "il compito affidato in futuro".

Se vuoi provare a utilizzare un pool di thread, il frammento di codice di cui sopra sarebbe diventato qualcosa di simile al seguente (utilizzando il Executors.newCachedThreadPool () metodo factory):

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

Morale della storia:

ereditano solo se si desidera sostituire alcuni comportamenti.

O piuttosto dovrebbe essere letto come:

ereditano meno, un'interfaccia più.

Bene tante buone risposte, voglio aggiungere di più su questo. Questo aiuterà a capire Extending v/s Implementing Thread.
estende lega due file di classe molto da vicino e può causare alcuni piuttosto difficile da affrontare con il codice.

Entrambi gli approcci fanno lo stesso lavoro, ma ci sono state alcune differenze.
La differenza più comune è

  1. Quando si estende classe Thread, dopo che non si può estendere qualsiasi altra classe che avete richiesto. (Come sapete, Java non consente ereditare più di una classe).
  2. Quando si implementa Runnable, è possibile risparmiare spazio per la classe di estendere qualsiasi altra classe in futuro o ora.

Tuttavia, una differenza significativa tra l'attuazione Runnable ed estendendo discussione è che
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.

Il seguente esempio vi aiuterà a capire più chiaramente

//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();
 }
}

Output del programma di cui sopra.

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

Nell'approccio interfaccia Runnable, si sta creando una sola istanza di una classe ed è stato condiviso da diversi thread. Quindi il valore del contatore viene incrementato per ogni accesso thread.

considerando che, approccio classe Thread, è necessario disporre di creare un'istanza separata per ogni accesso thread. Quindi memoria diverso viene allocata per ogni istanze di classe e ciascuno ha contatore separato, il valore rimane lo stesso, che significa che non incremento avviene perché nessuno di riferimento oggetto stesso.

Quando usare Runnable?
Utilizzare l'interfaccia Runnable quando si desidera accedere alle stesse risorse dal gruppo di fili. Evitare l'uso di classe Thread qui, perché la creazione di più oggetti consuma più memoria e diventa un grande sovraccarico di prestazioni.

Una classe che implementa Runnable non è un filo e solo una classe. Per un Runnable per diventare un thread, è necessario creare un'istanza di filo e per sé passando come destinazione.

Nella maggior parte dei casi, l'interfaccia Runnable dovrebbe essere usato se si è solo intenzione di eseguire l'override del metodo run() e non altri metodi di discussione. Questo è importante perché le classi non dovrebbero essere sottoclassi a meno che il programmatore intende sulla modifica o migliorare il comportamento fondamentale della classe.

Quando v'è la necessità di estendere una superclasse, che implementa l'interfaccia Runnable è più appropriato utilizzando la classe Thread. Perché possiamo estendere un'altra classe, mentre l'attuazione interfaccia Runnable per fare un thread.

Spero che questo vi aiuterà!

Una cosa che mi sorprende non è stato ancora menzionato è che l'attuazione Runnable rende la classe più flessibile.

Se si estende filo allora l'azione si sta facendo sta andando sempre essere in un thread. Tuttavia, se si implementa Runnable che non deve essere. È possibile eseguire in un filo, o passare a qualche tipo di servizio esecutore, o semplicemente passare intorno come attività all'interno di una singola applicazione filettato (forse per essere eseguito in un secondo momento, ma nello stesso filo). Le opzioni sono molto più aperta se si utilizza Runnable di quanto se si associa a voi stessi di Thread.

Se si vuole implementa o estende qualsiasi altra classe, allora l'interfaccia Runnable è più preferibile, in caso contrario, se non si vuole qualsiasi altra classe di estendere o implementare classe allora Thread è preferibile.

La differenza più comune è

entrare descrizione dell'immagine qui

Quando si extends Thread classe, dopo che non si può estendere qualsiasi altra classe che avete richiesto. (Come sapete, Java non consente ereditare più di una classe).

Quando si implements Runnable, è possibile risparmiare spazio per la classe di estendere qualsiasi altra classe in futuro o ora.

  • Java non supporta più le eredità, che significa che è possibile estendere una sola classe in Java quindi una volta che esteso classe Thread hai perso la tua occasione e non si può estendere o ereditare un'altra classe in Java.

  • Nella programmazione orientata agli oggetti, estendendo una classe significa generalmente, aggiungendo nuove funzionalità, e modificare o migliorare comportamenti. Se non stiamo facendo alcuna modifica sulla Discussione quindi utilizzare invece interfaccia Runnable.

  • interfaccia Runnable rappresenta un compito che può essere eseguito da una filettatura semplice o esecutori o qualsiasi altro mezzo. la separazione in modo logico di un'attività come Runnable dai filati è una buona decisione di design.

  • La separazione compito come Runnable significa che possiamo riutilizzare il compito e ha anche la libertà di eseguirlo da diversi mezzi. dal momento che non è possibile riavviare un thread una volta che completa. nuovo Runnable vs filetto per compito, Runnable è vincitore.

  • Java progettista riconosce questo ed è per questo Esecutori accettare Runnable come Task e hanno thread di lavoro che esegue quelli compito.

  • Ereditare tutti i metodi della discussione sono un ulteriore sovraccarico solo per rappresentare un compito che può essere fatto facilmente con Runnable.

Per gentile concessione da javarevisited.blogspot.com

Queste erano alcune delle differenze notevoli tra Discussione e Runnable in Java. Se conoscete altre differenze su Discussione vs Runnable che si prega di condividerlo tramite i commenti. Io personalmente uso Runnable oltre Discussione per questo scenario e raccomanda di utilizzare l'interfaccia Runnable o richiamabile in base al requisito.

Tuttavia, la differenza è significativa.

Quando si extends Thread classe, ogni del vostro thread crea un oggetto unico e associato con esso. Quando si implements Runnable, condivide lo stesso oggetto da più thread.

In realtà, non è saggio per confrontare Runnable e Thread con l'altro.

Questo due hanno una dipendenza e rapporto in multi-thread come rapporto Wheel and Engine di autoveicolo.

direi, c'è un solo modo per il multi-threading con due passaggi. Permettetemi di fare il mio punto.

Runnable:
Quando si implementa interface Runnable significa che si sta creando qualcosa che è run able in un thread diverso. Ora la creazione di qualcosa che può essere eseguito all'interno di un filo (eseguibile all'interno di un filo), non significa la creazione di un filo.
Così il MyRunnable classe è altro che una classe ordinaria con un metodo void run. Ed è oggetti saranno alcuni oggetti ordinari solo con un metodo run che eseguirà normalmente quando viene chiamato. (A meno che si passa l'oggetto in un thread).

Discussione:
class Thread, direi una classe molto speciale con la capacità di iniziare un nuovo thread che consente in realtà multi-threading attraverso il suo metodo start().

Perché non è saggio per confrontare?
Perché abbiamo bisogno di entrambi per il multi-threading.

Per Multi-threading abbiamo bisogno di due cose:

  • Qualcosa che può essere eseguito all'interno di un thread (Runnable).
  • qualcosa che può iniziare un nuovo thread (Thread).

Quindi è tecnicamente e teoricamente entrambi necessari per avviare un thread, uno sarà eseguire e uno sarà farlo funzionare (come Wheel and Engine di autoveicolo).

Ecco perché non è possibile avviare una discussione con MyRunnable è necessario passare ad un'istanza di Thread.

Ma è possibile creare ed eseguire un filo solo utilizzando class Thread perché Classe Thread implementa Runnable modo che tutti noi sappiamo Thread è anche un Runnable all'interno.

Infine Thread e Runnable sono complemento l'uno all'altro per il multithreading non concorrente o la sostituzione.

Si dovrebbe implementare Runnable, ma se si esegue su Java 5 o superiore, non si dovrebbe iniziare con new Thread ma usare un ExecutorService . Per i dettagli si veda:. Come implementare semplice threading in Java

Io non sono un esperto, ma mi viene in mente un motivo per implementare Runnable invece di estendere Discussione:. Java supporta solo l'ereditarietà singola, in modo da poter estendere solo una classe

Edit: Questo originariamente ha dichiarato: "L'implementazione di un'interfaccia richiede meno risorse." come pure, ma è necessario creare una nuova istanza Discussione in entrambi i casi, quindi questo è stato sbagliato.

Direi che c'è una terza via:

public class Something {

    public void justAnotherMethod() { ... }

}

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

Forse questo è influenzato un po 'dal mio recente l'uso pesante di Javascript e Actionscript 3, ma in questo modo la classe non ha bisogno di implementare un'interfaccia piuttosto vago come Runnable.

Con il rilascio di Java 8, ora c'è una terza opzione.

Runnable è interfaccia href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8"> funzionale, che significa che le istanze di esso possono essere creati con le espressioni lambda o il metodo di riferimento.

Il vostro esempio può essere sostituito con:

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

o se si desidera utilizzare un ExecutorService e un riferimento Metodo:

executor.execute(runner::run)

Queste non sono solo molto più breve di tuoi esempi, ma anche venire con molti dei vantaggi indicati in altre risposte di utilizzare Runnable sopra Thread, quale singolo responsabilità e con la composizione perché non stai specializzata comportamento del thread. In questo modo evita anche la creazione di una classe in più se tutto ciò che serve è un Runnable come si fa nei tuoi esempi.

di un'istanza di un interfaccia fornisce una separazione più netta tra il codice e l'attuazione di fili, quindi preferirei di implementare Runnable in questo caso.

Tutti qui sembra pensare che attuare Runnable è la strada da percorrere e non ho davvero d'accordo con loro, ma v'è anche un'opportunità di estendere Discussione a mio parere, in realtà si è dimostrata una sorta di esso nel codice.

Se si implementa Runnable allora la classe che implementa Runnable non ha alcun controllo sul nome del filo, è il codice chiamante che può impostare il nome del filo, in questo modo:

new Thread(myRunnable,"WhateverNameiFeelLike");

, ma se si estende Discussione poi si arriva a gestire questo all'interno della classe stessa (proprio come nel tuo esempio è il nome del filo 'ThreadB'). In questo caso:

A) potrebbe dare un nome più utile per il debug

B) stanno costringendo che quel nome da utilizzare per tutte le istanze di quella classe (a meno che non si ignora il fatto che si tratta di un filo e fare quanto sopra con esso come se fosse un Runnable, ma stiamo parlando di convention qui in qualsiasi caso in modo può ignorare questa possibilità mi sento).

Si potrebbe anche prendere ad esempio una traccia dello stack della sua creazione e l'uso che come il nome thread. Questo potrebbe sembrare strano, ma a seconda di come il codice è strutturato può essere molto utile per il debugging.

Questo potrebbe sembrare una piccola cosa, ma in cui si dispone di un'applicazione molto complessa con un sacco di discussioni e tutto ad un tratto le cose 'hanno smesso' (sia per ragioni di stallo o forse a causa di un difetto in un protocollo di rete che sarebbe meno evidente - o per altri motivi senza fine) quindi ottenere un dump dello stack da Java, dove tutti i fili sono chiamati 'filo-1', 'filo-2', 'filo-3' non è sempre molto utile (dipende da come le discussioni che sono strutturati e se si può utilmente dire che è che solo con la loro analisi dello stack -. non sempre è possibile se si utilizzano i gruppi di più thread in esecuzione tutti lo stesso codice)

Dopo aver detto che si potrebbe naturalmente anche fare quanto sopra in modo generico con la creazione di un'estensione della classe thread che imposta il suo nome ad una traccia dello stack del suo invito creazione e quindi utilizzare tale con le implementazioni Runnable invece dello standard classe java filettatura (vedi sotto), ma in aggiunta alla stack ci potrebbe essere più informazioni specifiche contesto che sarebbe utile nel nome del filo per il debug (un riferimento a una delle tante code o socket potrebbe elaborazione per esempio nel qual caso potrebbero preferire di estendere Discussione appositamente per questo caso in modo che si può avere la forza di compilatore (o gli altri usando le librerie) per passare in alcune informazioni (ad esempio la coda / presa in questione) per l'uso nel nome).

Ecco un esempio del filo generico con l'analisi dello stack chiama come il suo nome:

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"));
    }
}

Ed ecco un esempio di output confronto tra i due nomi:

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 perché:

  • lascia più flessibilità per il Eseguibile attuazione per estendere un'altra classe
  • separa il codice dal esecuzione
  • Consente di eseguire il eseguibile da un pool di thread, il filetto evento, o in qualsiasi altro modo il futuro.

Anche se non hai bisogno di niente di tutto questo ora, si potrebbe in futuro. Poiché non v'è alcun beneficio per Discussione prioritario, Runnable è una soluzione migliore.

Dato che questo è un argomento molto popolare e le buone risposte sono sparse ovunque e trattate in modo molto approfondito, ho ritenuto giustificabile raccogliere le buone risposte degli altri in una forma più concisa, in modo che i nuovi arrivati ​​abbiano una facile panoramica in anticipo:

  1. Di solito estendi una classe per aggiungere o modificare funzionalità.COSÌ, se non vuoi A sovrascrivere Qualunque Comportamento del thread, quindi utilizzare Runnable.

  2. Nella stessa luce, se non ti serve A ereditare metodi thread, puoi farne a meno sopraelevato utilizzando Runnable.

  3. Eredità unica:Se estendi Thread non puoi estenderlo da nessun'altra classe, quindi se è quello che devi fare, devi usare Runnable.

  4. È una buona progettazione separare la logica del dominio dai mezzi tecnici, in questo senso è meglio avere un'attività eseguibile isolando tuo compito da tuo corridore.

  5. Puoi eseguire lo stesso eseguibile oggetto più volte, un oggetto Thread, tuttavia, può essere avviato solo una volta.(Forse il motivo per cui gli esecutori accettano Runnable, ma non thread.)

  6. Se sviluppi la tua attività come Runnable, hai tutta la flessibilità su come utilizzarlo ora e in futuro.Puoi farlo funzionare contemporaneamente tramite Esecutori ma anche tramite Thread.E potresti comunque anche usarlo/chiamarlo non contemporaneamente all'interno dello stesso thread proprio come qualsiasi altro tipo/oggetto ordinario.

  7. Questo rende anche più facile separato logica dei compiti e concorrenza aspetti in tuo test unitari.

  8. Se sei interessato a questa domanda, potrebbe interessarti anche il differenza tra Callable e Runnable.

Differenza tra Estendere Discussione e implementazione di Runnable sono:

 entrare descrizione dell'immagine qui

Questo è discusso in Definizione e avvio di un tutorial Discussione :

  

Quale di questi idiomi si dovrebbe usare? Il primo linguaggio, che impiega un   oggetto Runnable, è più generale, in quanto l'oggetto Runnable può   sottoclasse una classe diversa Discussione. Il secondo idioma è più facile da usare   in applicazioni semplici, ma è limitata dal fatto che il vostro compito   classe deve essere un discendente di Discussione. Questa lezione si concentra sul primo   approccio, che separa il compito Runnable dall'oggetto filettatura   che esegue il compito. Non solo questo approccio più flessibile, ma   è applicabile ai API di gestione filo ad alto livello coperte   più tardi.

In altre parole, l'implementazione Runnable lavorerà in scenari in cui la classe si estende una classe diversa Thread. Java non supporta l'ereditarietà multipla. Inoltre, estendendo Thread non sarà possibile quando si utilizza alcune API di gestione filo ad alto livello. L'unico scenario in cui si estende Thread è preferibile è una piccola applicazione che non sarà soggetta ad aggiornamenti in futuro. E 'quasi sempre meglio per implementare Runnable in quanto è più flessibile come il vostro progetto cresce. Una modifica di progettazione non avrà un grande impatto, come si può implementare molte interfacce in Java, ma si estendono una sola classe.

Se non mi sbaglio, è più o meno simile a

Qual è la differenza tra un'interfaccia e classe astratta?

estende stabilisce " A " relazione e interfaccia fornisce " Ha un " capacità.

Preferisco implementa Runnable :

  1. Se non si dispone di estendere classe Thread e modificare Discussione implementazione dell'API di default
  2. Se si sta eseguendo un incendio e il comando dimentica
  3. Se sei già estendendo un'altra classe

Prefer " si estende Discussione ":

  1. Se si deve sostituire uno qualsiasi di questi href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html" metodi elencati nella pagina di documentazione di Oracle

In genere non è necessario sovrascrivere il comportamento Discussione. Così implementa Runnable è preferito per la maggior parte delle volte.

Su una nota diversa, utilizzando ExecutorService avanzato o ThreadPoolExecutorService API fornisce maggiore flessibilità e controllo.

Date un'occhiata a questa domanda SE:

ExecutorService vs casual Discussione Spawner

La spiegazione più semplice sarebbe implementando Runnable possiamo assegnare lo stesso oggetto in più thread e ogni azione Thread gli stessi stati dell'oggetto e comportamento.

Ad esempio, supponiamo che ci siano due fili, Thread1 mette un numero intero in una matrice e thread2 prende interi dal vettore che viene riempito. Si noti che, per Thread2 per funzionare ha bisogno di conoscere lo stato della matrice, sia Thread1 ha riempito in su oppure no.

L'implementazione Runnable permette di avere questa flessibilità di condividere l'oggetto, mentre extends Thread fa di creare nuovi oggetti per ogni thread quindi ogni aggiornamento che è fatto da Thread1 si perde a Thread2.

Separazione classe Thread dall'attuazione Runnable evita anche potenziali problemi di sincronizzazione tra il filo e il metodo run (). Un Runnable separata dà generalmente maggiore flessibilità in modo che il codice eseguibile viene fatto riferimento ed eseguito.

Quello è il S Di SOLIDO:Unica responsabilità.

UN filo incarna il contesto in esecuzione (come nel contesto di esecuzione:stack frame, ID thread, ecc.) del file esecuzione asincrona di un pezzo di codice.Quello pezzo di codice idealmente dovrebbe essere la stessa implementazione, se sincrono O asincrono.

Se li raggruppi insieme in un'unica implementazione, ne assegni due all'oggetto risultante non correlato cause del cambiamento:

  1. gestione dei thread nella tua applicazione (es.interrogando e modificando il contesto di esecuzione)
  2. algoritmo implementato dal pezzo di codice (la parte eseguibile)

Se il linguaggio che usi supporta classi parziali o ereditarietà multipla, puoi separare ciascuna causa nella propria super classe, ma si riduce allo stesso modo di comporre i due oggetti, poiché i loro set di funzionalità non si sovrappongono.Questo è per la teoria.

In pratica, in generale, un programma non ha bisogno di essere più complesso del necessario.Se hai un thread che lavora su un'attività specifica, senza mai modificare tale attività, probabilmente non ha senso rendere le attività classi separate e il tuo codice rimane più semplice.

Nel contesto di Giava, poiché la struttura è già là, probabilmente è più semplice iniziare direttamente con stand alone Runnable classi e passare le loro istanze a Thread (O Executor) istanze.Una volta usato a quel modello, non è più difficile da usare (o addirittura leggere) rispetto al semplice thread eseguibile.

Una ragione che ci si vuole implementare un'interfaccia piuttosto che estendere una classe di base è che si sta già estendendo qualche altra classe. È possibile estendere una sola classe, ma è possibile realizzare qualsiasi numero di interfacce.

Se si estende Thread, si sta fondamentalmente prevenire la logica che deve essere eseguito da qualsiasi altro thread di 'questo'. Se si desidera solo alcuni thread per eseguire la logica, è meglio implementare solo eseguibile.

se si utilizza eseguibile è possibile salvare lo spazio di estendere a qualsiasi vostra altra classe.

Possiamo ri-visitare il motivo di base che volevamo la nostra classe di comportarsi come un Thread? Non v'è nessuna ragione al mondo, volevamo solo per eseguire un compito, molto probabilmente in una modalità asincrona, che significa appunto che l'esecuzione del compito deve diramano dal nostro thread principale e il filo conduttore se termina presto, possono o non aspettare per il percorso ramificata (task).

Se questo è l'intero scopo, allora dove vedo la necessità di un thread specializzato. Questo può essere realizzato con la scelta di un thread RAW dal pool di thread del sistema e l'assegnazione è il nostro compito (può essere un'istanza della nostra classe) e che è esso.

Cerchiamo quindi obbediamo il concetto OOPs e scrivere una classe del tipo di cui abbiamo bisogno. Ci sono molti modi per fare le cose, che lo fanno nelle materie modo giusto.

Abbiamo bisogno di un compito, in modo da scrivere una definizione compito che può essere eseguito su un filo. Così utilizzare Runnable.

Ricordate sempre implements è usato specialmente per conferire un comportamento e extends viene utilizzato per impartire una caratteristica / proprietà.

Non vogliamo proprietà del thread, invece vogliamo che la nostra classe di comportarsi come un compito che può essere eseguito.

Si, Se si chiama ThreadA chiamata, quindi non c'è bisogno di chiamare il metodo di avvio e il metodo di esecuzione è chiamata dopo chiamata solo la classe ThreadA. Ma se l'uso della chiamata ThreadB quindi bisogno di necessario il filo di partenza per metodo di esecuzione delle chiamate. Se si dispone di più aiuto, mi ha risposto.

Lo trovo è più utile da usare Runnable per tutti i motivi citati, ma a volte mi piace estendere Discussione in modo da poter creare il mio metodo di arresto filo e chiamarlo direttamente sul filo che ho creato.

Java non supporta l'ereditarietà multipla, quindi se si estende classe Thread allora nessun altra classe sarà esteso.

Per esempio: Se si crea un applet, allora deve estende classe Applet ecco l'unico modo per creare filo viene implementando interfaccia Runnable

Runnable è un'interfaccia, mentre Thread è una classe che implementa questa interfaccia. Da un punto di vista progettuale, dovrebbe esserci una netta separazione tra come un'attività viene definito e tra come viene eseguito. Il primo è la responsabilità di un'implementazione Runnalbe, e la seconda è compito della classe Thread. Nella maggior parte dei casi di applicazione Runnable è la strada giusta da seguire.

Differenza tra Filetto ed eseguibili .Se creiamo filettatura utilizzando classe Thread allora Numero di filo pari al numero di oggetti che abbiamo creato. Se stiamo creando filo implementando l'interfaccia eseguibile allora possiamo usare singolo oggetto per la creazione di più thread.So singolo oggetto è condiviso da più Thread.So richiederà meno memoria

Quindi, a seconda del fabbisogno, se i nostri dati non è senstive. Così può essere condiviso tra Discussione più siamo in grado di utilizzare l'interfaccia Runnable.

L'aggiunta miei due centesimi qui - Sempre per quanto possibile l'uso implements Runnable. Qui di seguito sono due avvertimenti sul motivo per cui non si dovrebbe usare extends Threads

  1. Idealmente si dovrebbe mai estendere la classe Thread; la classe Thread dovrebbe essere fatto final. Almeno i suoi metodi come thread.getId(). Vedere questa discussione per un bug relativo al Threads estendono.

  2. Coloro che amano risolvere enigmi può vedere un altro effetto collaterale di estendere Discussione. Il codice qui sotto stamperà codice irraggiungibile quando nessuno li sta notificando.

Si prega di consultare 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 ");
        }
    } 
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top