Depuis le temps que j'ai passé avec les threads en Java, j'ai trouvé ces deux façons d'écrire des threads:
Avec implements Runnable
:
public class MyRunnable implements Runnable {
public void run() {
//Code
}
}
//Started with a "new Thread(new MyRunnable()).start()" call
Ou, avec extends Thread
:
public class MyThread extends Thread {
public MyThread() {
super("MyThread");
}
public void run() {
//Code
}
}
//Started with a "new MyThread().start()" call
Y a-t-il une différence significative entre ces deux blocs de code?
java
multithreading
runnable
implements
java-threads
user65374
la source
la source
interrupt()
. Encore une fois, c'est une idée, elle pourrait être utile dans le bon cas, mais je ne la recommande pas.Réponses:
Oui: l'implémentation
Runnable
est la façon préférée de le faire, OMI. Vous ne spécialisez pas vraiment le comportement du thread. Vous lui donnez juste quelque chose à exécuter. Cela signifie que la composition est la voie à suivre philosophiquement "la plus pure".En termes pratiques , cela signifie que vous pouvez également implémenter
Runnable
et étendre à partir d'une autre classe.la source
if (numberCores > 4) myExecutor.excute(myRunnable); else myRunnable.run()
extends Thread
et si vous ne voulez pas de thread, pourquoi implémenteriez-vous mêmeRunnable
...tl; dr: implémente Runnable, c'est mieux. Cependant, la mise en garde est importante
En général, je recommanderais d'utiliser quelque chose comme
Runnable
plutôt queThread
parce qu'il vous permet de garder votre travail associé de manière lâche à votre choix de concurrence. Par exemple, si vous utilisez unRunnable
et décidez plus tard que cela ne nécessite pas le sienThread
, vous pouvez simplement appeler threadA.run ().Mise en garde: ici, je déconseille fortement l'utilisation de threads bruts. Je préfère de beaucoup l'utilisation de appelables et FutureTasks (De la javadoc: « Un calcul asynchrone résiliable »). L'intégration des délais d'attente, l'annulation correcte et la mise en commun des threads de la prise en charge de la concurrence moderne me sont beaucoup plus utiles que des piles de threads bruts.
Suivi: il existe un
FutureTask
constructeur qui vous permet d'utiliser Runnables (si c'est ce avec quoi vous êtes le plus à l'aise) tout en bénéficiant des outils de concurrence modernes. Pour citer le javadoc :Si vous n'avez pas besoin d'un résultat particulier, envisagez d'utiliser des constructions du formulaire:
Donc, si nous les remplaçons
runnable
par les vôtresthreadA
, nous obtenons ce qui suit:Une autre option qui vous permet de rester plus proche de Runnables est un ThreadPoolExecutor . Vous pouvez utiliser la méthode execute pour passer un Runnable pour exécuter "la tâche donnée dans le futur".
Si vous souhaitez essayer d'utiliser un pool de threads, le fragment de code ci-dessus deviendrait quelque chose comme ceci (en utilisant la méthode d'usine Executors.newCachedThreadPool () ):
la source
es
serait mieux comme un champ statique (ou injecté) donc il n'est créé qu'une seule fois.FutureTask
directement n'est généralement pas ce que vous voulez faire.ExecutorService
s créera ce quiFuture
vous convient lorsque voussubmit
aRunnable
/Callable
à eux. De même pourScheduledExecutorService
s etScheduledFuture
quand vousschedule
unRunnable
/Callable
.Morale de l'histoire:
Héritez uniquement si vous souhaitez remplacer un comportement.
Ou plutôt il doit être lu comme:
Héritez moins, interférez plus.
la source
run()
méthode.java.lang.Thread
en remplaçant larun()
méthode. Dans ce cas, vous devez remplacer lastart()
méthode, je suppose. Normalement, vous réutilisez simplement le comportement dujava.lang.Thread
en injectant votre bloc d'exécution dans larun()
méthode.Eh bien tant de bonnes réponses, je veux ajouter plus à ce sujet. Cela vous aidera à comprendre
Extending v/s Implementing Thread
.Extends lie très étroitement deux fichiers de classe et peut rendre le code assez difficile à gérer.
Les deux approches font le même travail mais il y a eu quelques différences.
La différence la plus courante est
Cependant, une différence significative entre l'implémentation de Runnable et l'extension de Thread est que
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.
L'exemple suivant vous aidera à mieux comprendre
Sortie du programme ci-dessus.
Dans l'approche de l'interface exécutable, une seule instance d'une classe est en cours de création et elle a été partagée par différents threads. Ainsi, la valeur du compteur est incrémentée pour chaque accès au thread.
Alors que, l'approche de la classe Thread, vous devez créer une instance distincte pour chaque accès au thread. Par conséquent, une mémoire différente est allouée pour chaque instance de classe et chacune a un compteur séparé, la valeur reste la même, ce qui signifie qu'aucun incrément ne se produira car aucune des références d'objet n'est identique.
Quand utiliser Runnable?
Utilisez l'interface exécutable lorsque vous souhaitez accéder aux mêmes ressources à partir du groupe de threads. Évitez d'utiliser la classe Thread ici, car la création d'objets multiples consomme plus de mémoire et cela devient une surcharge importante de performances.
Une classe qui implémente Runnable n'est pas un thread et juste une classe. Pour qu'un Runnable devienne un Thread, vous devez créer une instance de Thread et vous passer comme cible.
Dans la plupart des cas, l'interface Runnable doit être utilisée si vous prévoyez uniquement de remplacer la
run()
méthode et aucune autre méthode Thread. Ceci est important car les classes ne doivent pas être sous-classées sauf si le programmeur a l'intention de modifier ou d'améliorer le comportement fondamental de la classe.Lorsqu'il est nécessaire d'étendre une superclasse, l'implémentation de l'interface Runnable est plus appropriée que l'utilisation de la classe Thread. Parce que nous pouvons étendre une autre classe tout en implémentant l'interface Runnable pour créer un thread.
J'espère que cela vous aidera!
la source
ExtendsThread et = new ExtendsThread();
Thread tc1 = new Thread(et);
tc1.start();
Thread.sleep(1000);
Thread tc2 = new Thread(et);
tc2.start();
Thread.sleep(1000);
Thread tc3 = new Thread(et);
tc3.start();
est-ce plus clair?Thread
incrémentée, la déclaration est-elleby extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance
alors fausse? Sinon, quel est le cas qui le démontre?Une chose qui m'étonne n'a pas encore été mentionnée: l'implémentation
Runnable
rend votre classe plus flexible.Si vous étendez le thread, l'action que vous faites sera toujours dans un thread. Cependant, si vous l'implémentez,
Runnable
cela ne doit pas l'être. Vous pouvez l'exécuter dans un thread, ou le transmettre à une sorte de service d'exécuteur, ou simplement le passer comme tâche dans une seule application threadée (peut-être à exécuter ultérieurement, mais dans le même thread). Les options sont beaucoup plus ouvertes si vous utilisez simplementRunnable
que si vous vous y liezThread
.la source
Thread
objet aussi parce queThread implements Runnable
… ;-) Mais ça «se sent mieux» de faire ces choses avec unRunnable
que de les faire avec unThread
!Thread
ajoute beaucoup de choses supplémentaires dont vous n'avez pas besoin, et dans de nombreux cas, vous ne voulez pas. Il vaut toujours mieux mettre en œuvre l'interface qui correspond à ce que vous faites réellement.Si vous voulez implémenter ou étendre une autre classe, alors l'
Runnable
interface est plus préférable, sinon, si vous ne voulez pas qu'une autre classe s'étende ou implémente, alors laThread
classe est préférable.La différence la plus courante est
Quand vous
extends Thread
classe, après cela, vous ne pouvez pas étendre toute autre classe dont vous aviez besoin. (Comme vous le savez, Java ne permet pas d'hériter de plus d'une classe).Lorsque vous
implements Runnable
, vous pouvez économiser de l'espace pour votre classe afin d'étendre n'importe quelle autre classe à l'avenir ou maintenant.Java ne prend pas en charge plusieurs héritages, ce qui signifie que vous ne pouvez étendre qu'une seule classe en Java, donc une fois que vous avez étendu la classe Thread, vous avez perdu votre chance et ne pouvez pas étendre ou hériter d'une autre classe en Java.
Dans la programmation orientée objet, l'extension d'une classe signifie généralement l'ajout de nouvelles fonctionnalités et la modification ou l'amélioration des comportements. Si nous n'effectuons aucune modification sur Thread, utilisez plutôt l'interface Runnable.
L'interface exécutable représente une tâche qui peut être exécutée par un thread simple ou des exécuteurs ou tout autre moyen. la séparation logique de Task comme Runnable que Thread est une bonne décision de conception.
Séparer la tâche en tant que Runnable signifie que nous pouvons réutiliser la tâche et avoir également la liberté de l'exécuter à partir de différents moyens. car vous ne pouvez pas redémarrer un thread une fois qu'il est terminé. Runnable vs Thread pour la tâche, Runnable est gagnant.
Le concepteur Java le reconnaît et c'est pourquoi les exécuteurs acceptent Runnable comme tâche et ils ont un thread de travail qui exécute ces tâches.
L'héritage de toutes les méthodes Thread est une surcharge supplémentaire juste pour représenter une tâche qui peut être effectuée facilement avec Runnable.
Gracieuseté de javarevisited.blogspot.com
Ce sont quelques-unes des différences notables entre Thread et Runnable en Java. Si vous connaissez d'autres différences sur Thread vs Runnable que s'il vous plaît partagez-les via des commentaires. J'utilise personnellement Runnable sur Thread pour ce scénario et recommande d'utiliser l'interface Runnable ou Callable en fonction de vos besoins.
Cependant, la différence significative est.
Lorsque vous
extends Thread
classe, chacun de vos threads crée un objet unique et s'associe avec lui. Lorsque vousimplements Runnable
, il partage le même objet sur plusieurs threads.la source
En fait, il est sage de ne pas comparer
Runnable
etThread
les uns avec les autres.Ces deux ont une dépendance et une relation dans le multi-threading tout comme la
Wheel and Engine
relation du véhicule à moteur.Je dirais qu'il n'y a qu'une seule façon pour le multi-thread avec deux étapes. Permettez-moi de faire valoir mon point de vue.
Exécutable:
lors de l'implémentation,
interface Runnable
cela signifie que vous créez quelque chose qui se trouverun able
dans un thread différent. Maintenant, créer quelque chose qui peut s'exécuter à l'intérieur d'un thread (exécutable à l'intérieur d'un thread), ne signifie pas créer un thread.La classe
MyRunnable
n'est donc rien d'autre qu'une classe ordinaire avec unevoid run
méthode. Et ses objets seront des objets ordinaires avec seulement une méthoderun
qui s'exécutera normalement lors de l'appel. (sauf si nous passons l'objet dans un fil).Thread:,
class Thread
je dirais Une classe très spéciale avec la capacité de démarrer un nouveau Thread qui permet en fait le multi-threading via sastart()
méthode.Pourquoi pas sage de comparer?
Parce que nous avons besoin des deux pour le multi-threading.
Pour le multi-threading, nous avons besoin de deux choses:
Donc, techniquement et théoriquement, les deux sont nécessaires pour démarrer un thread, l'un fonctionnera et l'autre le fera fonctionner (comme
Wheel and Engine
pour un véhicule à moteur).C'est pourquoi vous ne pouvez pas démarrer un thread avec lequel vous
MyRunnable
devez le passer à une instance deThread
.Mais il est possible de créer et d'exécuter un thread uniquement en utilisant
class Thread
parce que la classeThread
implémenteRunnable
donc nous savons tous que c'estThread
aussi unRunnable
intérieur.Enfin
Thread
etRunnable
sont complémentaires les uns des autres pour le multithreading non concurrent ou de remplacement.la source
ThreadA
n'a plus de sensVous devez implémenter Runnable, mais si vous utilisez Java 5 ou supérieur, vous ne devez pas le démarrer avec
new Thread
mais utiliser un ExecutorService à la place. Pour plus de détails, voir: Comment implémenter un filetage simple en Java .la source
Je ne suis pas un expert, mais je peux penser à une raison pour implémenter Runnable au lieu d'étendre Thread: Java ne prend en charge que l'héritage unique, vous ne pouvez donc étendre qu'une seule classe.
Edit: Cela disait à l'origine "L'implémentation d'une interface nécessite moins de ressources." également, mais vous devez créer une nouvelle instance de thread de toute façon, donc c'était faux.
la source
Je dirais qu'il y a une troisième voie:
Peut-être que cela est un peu influencé par ma récente utilisation intensive de Javascript et Actionscript 3, mais de cette façon, votre classe n'a pas besoin d'implémenter une interface assez vague comme
Runnable
.la source
Avec la sortie de Java 8, il y a maintenant une troisième option.
Runnable
est une interface fonctionnelle , ce qui signifie que ses instances peuvent être créées avec des expressions lambda ou des références de méthode.Votre exemple peut être remplacé par:
ou si vous souhaitez utiliser une
ExecutorService
référence de méthode et:Ce sont non seulement beaucoup plus courte que vos exemples, mais viennent aussi avec un grand nombre des avantages énoncés dans d' autres réponses de l' utilisation de
Runnable
plusThread
, comme la responsabilité unique et la composition à l' aide parce que vous n'êtes pas spécialisé le comportement du fil. De cette façon, vous évitez également de créer une classe supplémentaire si tout ce dont vous avez besoin est unRunnable
comme vous le faites dans vos exemples.la source
() -> {}
c'est censé représenter la logique personnalisée dont quelqu'un a besoin? Il serait donc préférable de le dire comme() -> { /* Code here */ }
?L'instanciation d'une interface donne une séparation plus nette entre votre code et l'implémentation des threads, donc je préfère implémenter Runnable dans ce cas.
la source
Tout le monde ici semble penser que l'implémentation de Runnable est la voie à suivre et je ne suis pas vraiment en désaccord avec eux, mais il y a aussi un argument pour étendre Thread à mon avis, en fait, vous l'avez en quelque sorte démontré dans votre code.
Si vous implémentez Runnable, la classe qui implémente Runnable n'a aucun contrôle sur le nom du thread, c'est le code appelant qui peut définir le nom du thread, comme ceci:
mais si vous étendez Thread, vous pouvez gérer cela au sein de la classe elle-même (tout comme dans votre exemple, vous nommez le thread 'ThreadB'). Dans ce cas, vous:
A) pourrait lui donner un nom plus utile à des fins de débogage
B) forcent à ce que ce nom soit utilisé pour toutes les instances de cette classe (à moins que vous ignoriez le fait qu'il s'agit d'un thread et que vous fassiez ce qui précède comme s'il s'agissait d'un Runnable, mais nous parlons ici de convention dans tous les cas, donc ignorer cette possibilité que je ressens).
Vous pouvez même par exemple prendre une trace de pile de sa création et l'utiliser comme nom de thread. Cela peut sembler étrange, mais selon la structure de votre code, il peut être très utile à des fins de débogage.
Cela peut sembler être une petite chose mais où vous avez une application très complexe avec beaucoup de threads et tout d'un coup, les choses se sont «arrêtées» (soit pour des raisons de blocage ou peut-être à cause d'une faille dans un protocole réseau qui serait moins évidente - ou d'autres raisons infinies), puis obtenir un vidage de pile à partir de Java où tous les threads sont appelés «Thread-1», «Thread-2», «Thread-3» n'est pas toujours très utile (cela dépend de la façon dont vos threads sont structuré et si vous pouvez dire lequel est juste par leur trace de pile - pas toujours possible si vous utilisez des groupes de plusieurs threads exécutant tous le même code).
Cela dit, vous pouvez bien sûr également faire ce qui précède de manière générique en créant une extension de la classe de threads qui définit son nom sur une trace de pile de son appel de création, puis l'utiliser avec vos implémentations Runnable au lieu de la classe de thread Java standard (voir ci-dessous) mais en plus de la trace de la pile, il pourrait y avoir plus d'informations spécifiques au contexte qui seraient utiles dans le nom du thread pour le débogage (une référence à l'une des nombreuses files d'attente ou sockets qu'il pourrait traiter, par exemple, auquel cas vous pourriez préférer étendez Thread spécifiquement pour ce cas afin que le compilateur vous force (ou que d'autres utilisent vos bibliothèques) à passer certaines informations (par exemple la file d'attente / socket en question) pour une utilisation dans le nom).
Voici un exemple de thread générique avec la trace de pile appelante comme nom:
et voici un échantillon de la sortie comparant les deux noms:
la source
Runnable
peut en effet contrôler le nom du thread, car le thread exécutant le code est par définition le thread actuel (et tout code qui passe les contrôles de sécurité a le contrôle sur les noms des threads). Étant donné que vous consacrez la moitié de votre message à "omg, qu'en est-il des noms de threads!", Cela semble être un gros problème.Exécutable car:
Même si vous n'avez besoin de rien de tout cela maintenant, vous pourrez le faire à l'avenir. Puisqu'il n'y a aucun avantage à remplacer Thread, Runnable est une meilleure solution.
la source
Étant donné que c'est un sujet très populaire et que les bonnes réponses sont réparties partout et traitées en profondeur, j'ai pensé qu'il était justifié de compiler les bonnes réponses des autres dans une forme plus concise, de sorte que les nouveaux arrivants ont un aperçu facile à l'avance:
Vous étendez généralement une classe pour ajouter ou modifier des fonctionnalités. Donc, si vous ne souhaitez pas remplacer un comportement de thread , utilisez Runnable.
De la même manière, si vous n'avez pas besoin d' hériter des méthodes de thread, vous pouvez vous passer de cette surcharge en utilisant Runnable.
Héritage unique : si vous étendez Thread, vous ne pouvez pas l'étendre à partir d'une autre classe, donc si c'est ce que vous devez faire, vous devez utiliser Runnable.
Il est judicieux de séparer la logique du domaine des moyens techniques, dans ce sens, il est préférable d'avoir une tâche exécutable isolant votre tâche de votre coureur .
Vous pouvez exécuter le même objet Runnable plusieurs fois , un objet Thread, cependant, ne peut être démarré qu'une seule fois. (Peut-être la raison pour laquelle les exécuteurs acceptent les runnables, mais pas les threads.)
Si vous développez votre tâche en tant que Runnable, vous avez toute la flexibilité nécessaire pour l'utiliser maintenant et à l'avenir . Vous pouvez le faire exécuter simultanément via Executors mais aussi via Thread. Et vous pouvez toujours l'utiliser / l'appeler de manière non simultanée dans le même thread, comme tout autre type / objet ordinaire.
Cela facilite également la séparation des aspects de logique de tâche et de concurrence dans vos tests unitaires .
Si vous êtes intéressé par cette question, vous pourriez également être intéressé par la différence entre Callable et Runnable .
la source
Différence entre l'extension de thread et l'implémentation de Runnable:
la source
Ceci est abordé dans le didacticiel Oracle Defining and Starting a Thread :
En d'autres termes, l'implémentation
Runnable
fonctionnera dans des scénarios où votre classe étend une classe autre queThread
. Java ne prend pas en charge l'héritage multiple. De plus, l'extensionThread
ne sera pas possible lors de l'utilisation de certaines API de gestion de threads de haut niveau. Le seul scénario où l'extensionThread
est préférable est dans une petite application qui ne sera pas soumise à des mises à jour à l'avenir. Il est presque toujours préférable de l'implémenterRunnable
car il est plus flexible à mesure que votre projet se développe. Un changement de conception n'aura pas d'impact majeur car vous pouvez implémenter de nombreuses interfaces en java, mais étendre une seule classe.la source
L'explication la plus simple serait d'implémenter que
Runnable
nous pouvons affecter le même objet à plusieurs threads et que chacunThread
partage les mêmes états et comportements d'objet.Par exemple, supposons qu'il existe deux threads, thread1 place un entier dans un tableau et thread2 prend des entiers dans le tableau lorsque le tableau est rempli. Notez que pour que thread2 fonctionne, il doit connaître l'état du tableau, que thread1 l' ait rempli ou non.
L'implémentation
Runnable
vous permet d'avoir cette flexibilité pour partager l'objet tandis queextends Thread
vous permet de créer de nouveaux objets pour chaque thread donc toute mise à jour effectuée par thread1 est perdue pour thread2.la source
Si je ne me trompe pas, c'est plus ou moins semblable à
Quelle est la différence entre une interface et une classe abstraite?
étend établit la relation « est un » et l'interface fournit la capacité « a une ».
Préférer implémente Runnable :
Préférez " étend le fil ":
En règle générale, vous n'avez pas besoin de remplacer le comportement du thread. L' implémentation de Runnable est donc préférable la plupart du temps.
Sur une note différente, l'utilisation avancée
ExecutorService
ouThreadPoolExecutorService
API offre plus de flexibilité et de contrôle.Jetez un oeil à cette question SE:
ExecutorService vs Casual Thread Spawner
la source
La séparation de la classe Thread de l'implémentation Runnable évite également les problèmes de synchronisation potentiels entre le thread et la méthode run (). Un Runnable séparé donne généralement une plus grande flexibilité dans la façon dont le code exécutable est référencé et exécuté.
la source
C'est le S de SOLID : responsabilité unique.
Un thread incarne le contexte d'exécution (comme dans le contexte d'exécution: cadre de pile, identifiant de thread, etc.) de l' exécution asynchrone d'un morceau de code. Idéalement, ce morceau de code devrait être la même implémentation, qu'elle soit synchrone ou asynchrone .
Si vous les regroupez dans une implémentation, vous attribuez à l'objet résultant deux causes de changement indépendantes :
Si le langage que vous utilisez prend en charge les classes partielles ou l'héritage multiple, vous pouvez alors séparer chaque cause dans sa propre super classe, mais cela revient à la même chose que la composition des deux objets, car leurs ensembles de fonctionnalités ne se chevauchent pas. C'est pour la théorie.
Dans la pratique, d'une manière générale, un programme n'a pas besoin d'être plus complexe que nécessaire. Si vous avez un thread travaillant sur une tâche spécifique, sans jamais changer cette tâche, il est probablement inutile de faire des classes de tâches séparées, et votre code reste plus simple.
Dans le contexte de Java , puisque la fonction est déjà là , il est probablement plus facile de démarrer directement avec des
Runnable
classes autonomes et de passer leurs instances àThread
(ouExecutor
) des instances. Une fois habitué à ce modèle, il n'est pas plus difficile à utiliser (ou même à lire) que le cas de thread exécutable simple.la source
L'une des raisons pour lesquelles vous souhaitez implémenter une interface plutôt que d'étendre une classe de base est que vous étendez déjà une autre classe. Vous ne pouvez étendre qu'une seule classe, mais vous pouvez implémenter n'importe quel nombre d'interfaces.
Si vous étendez Thread, vous empêchez essentiellement que votre logique soit exécutée par un autre thread que «this». Si vous souhaitez uniquement un thread pour exécuter votre logique, il est préférable de simplement implémenter Runnable.
la source
si vous utilisez runnable, vous pouvez économiser de l'espace pour l'étendre à n'importe laquelle de vos autres classes.
la source
Pouvons-nous revoir la raison fondamentale pour laquelle nous voulions que notre classe se comporte comme un
Thread
? Il n'y a aucune raison, nous voulions simplement exécuter une tâche, très probablement en mode asynchrone, ce qui signifie précisément que l'exécution de la tâche doit dériver de notre thread principal et du thread principal si elle se termine tôt, peut ou peut ne pas attendre pour le chemin ramifié (tâche).Si tel est le but, alors où puis-je voir la nécessité d'un fil spécialisé. Cela peut être accompli en ramassant un thread RAW dans le pool de threads du système et en lui assignant notre tâche (peut être une instance de notre classe) et c'est tout.
Obéissons donc au concept des POO et écrivons une classe du type dont nous avons besoin. Il existe de nombreuses façons de faire les choses, le faire correctement compte.
Nous avons besoin d'une tâche, alors écrivez une définition de tâche qui peut être exécutée sur un thread. Utilisez donc Runnable.
Rappelez
implements
- vous toujours est spécialement utilisé pour conférer un comportement etextends
est utilisé pour conférer une caractéristique / propriété.Nous ne voulons pas de la propriété du thread, mais nous voulons que notre classe se comporte comme une tâche qui peut être exécutée.
la source
Oui, si vous appelez un appel ThreadA, vous n'avez pas besoin d'appeler la méthode start et la méthode run est appelée uniquement après l'appel de la classe ThreadA. Mais si vous utilisez l'appel ThreadB, vous devez alors utiliser le thread de démarrage pour la méthode d'exécution des appels. Si vous avez plus d'aide, répondez-moi.
la source
Je trouve qu'il est très utile d'utiliser Runnable pour toutes les raisons mentionnées, mais parfois j'aime étendre Thread pour pouvoir créer ma propre méthode d'arrêt de thread et l'appeler directement sur le thread que j'ai créé.
la source
Java ne prend pas en charge l'héritage multiple, donc si vous étendez la classe Thread, aucune autre classe ne sera étendue.
Par exemple: si vous créez une applet, elle doit étendre la classe Applet, donc ici la seule façon de créer un thread est d'implémenter l'interface Runnable
la source
Runnable
est une interface, tandis queThread
est une classe qui implémente cette interface. Du point de vue de la conception, il devrait y avoir une séparation nette entre la façon dont une tâche est définie et entre la façon dont elle est exécutée. Le premier est la responsabilité d'uneRunnalbe
mise en œuvre, et le second est le travail de laThread
classe. Dans la plupart des cas, la mise en œuvreRunnable
est la bonne façon de suivre.la source
Différence entre Thread et runnable. Si nous créons Thread en utilisant la classe Thread, alors Number of thread égal au nombre d'objet que nous avons créé. Si nous créons un thread en implémentant l'interface exécutable, nous pouvons utiliser un seul objet pour créer plusieurs threads. Ainsi, un seul objet est partagé par plusieurs Thread. Cela prendra donc moins de mémoire
Donc, selon l'exigence si nos données ne sont pas sensibles. Donc, il peut être partagé entre plusieurs threads, nous pouvons utiliser l'interface Runnable.
la source
Ajouter mes deux cents ici - Toujours dans la mesure du possible
implements Runnable
. Voici deux mises en garde sur les raisons pour lesquelles vous ne devriez pas utiliserextends Thread
sIdéalement, vous ne devriez jamais étendre la classe Thread; le
Thread
cours doit être faitfinal
. Au moins ses méthodes commethread.getId()
. Voir cette discussion pour un bogue lié à l'extension deThread
s.Ceux qui aiment résoudre des énigmes peuvent voir un autre effet secondaire de l'extension du fil. Le code ci-dessous imprimera le code inaccessible lorsque personne ne les notifie.
Veuillez consulter http://pastebin.com/BjKNNs2G .
la source