Question

De quelle heure j'ai passé avec des fils en Java, j'ai trouvé ces deux façons d'écrire des fils:

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 at-il de différence significative dans ces deux blocs de code?

Était-ce utile?

La solution

Oui: implémente Runnable est le meilleur moyen de le faire, l'OMI. Vous n'êtes pas vraiment spécialisé le comportement du fil. Vous êtes juste en lui donnant quelque chose à courir. Cela signifie de composition est le philosophiquement façon plus "purs" pour aller.

pratique , cela signifie que vous pouvez mettre en œuvre Runnable et étendre d'une autre classe ainsi.

Autres conseils

tl; dr: implémente Runnable est mieux. Cependant, la mise en garde est importante

En général, je recommande d'utiliser quelque chose comme Runnable plutôt que Thread parce qu'il vous permet de garder votre travail que vaguement couplé avec votre choix de la concurrence. Par exemple, si vous utilisez un Runnable et décider par la suite que cela ne nécessitent en fait ses propres Thread, vous pouvez simplement appeler threadA.run ().

Caveat: Par ici, je recommandent fortement l'utilisation des Threads premières. 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, et la bonne annulation de mise en commun fil du support moderne sont à la concurrence me tous beaucoup plus utiles que les piles de fils premières.

Suivi: il y a une Pour citer javadoc:

Si vous n'avez pas besoin d'un résultat particulier, envisager d'utiliser des constructions de la forme:

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

Alors, si nous remplaçons leur runnable avec votre threadA, nous obtenons les éléments suivants:

new FutureTask<Object>(threadA, null)

Une autre option qui vous permet de rester plus proche de runnables est un ThreadPoolExecutor . Vous pouvez utiliser le méthode execute pour passer dans 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 ce qui suit (en utilisant le Executors.newCachedThreadPool () de la méthode de fabrique):

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

Morale de l'histoire:

que si vous Hérite voulez remplacer un comportement.

Ou plutôt il doit être lu comme:

moins Hérite, interface plus.

Eh bien tant de bonnes réponses, je veux ajouter plus à ce sujet. Cela vous aidera à comprendre Extending v/s Implementing Thread.
Prolonge se fixe très près deux fichiers de classe et peut causer une assez difficile de traiter avec le code.

Les deux approches font le même travail, mais il y a eu quelques différences.
La différence la plus courante est

  1. Lorsque vous étendez la classe fil, après que vous ne pouvez pas étendre une autre classe que vous devez. (Comme vous le savez, Java ne permet pas hériter de plus d'une classe).
  2. Lorsque vous implémentez Runnable, vous pouvez économiser de l'espace pour votre classe d'étendre toute autre classe à l'avenir ou maintenant.

Cependant, un différence significative entre la mise en œuvre Runnable et l'extension de cette discussion 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

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

Sortie du programme ci-dessus.

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

Dans l'approche de l'interface Runnable, une seule instance d'une classe est en cours de création et il a été partagée par différents threads. Ainsi, la valeur du compteur est incrémenté pour chaque accès fil.

considérant que, approche de classe de fil, vous devez avoir à créer une instance distincte pour chaque accès fil. D'où la mémoire est allouée différente pour chaque cas de classe et chacun a compteur séparé, la valeur reste la même, ce qui signifie pas d'augmentation se produira, car aucun de la référence d'objet est le même.

Quand utiliser Runnable? Utilisez l'interface Runnable lorsque vous souhaitez accéder aux mêmes ressources du groupe de threads. Évitez d'utiliser la classe de discussion ici, parce que la création d'objets multiples consomme plus de mémoire et il devient un grand frais généraux de performance.

Une classe qui implémente Runnable est pas un fil et juste une classe. Pour un Runnable pour devenir un thread, vous devez créer une instance de discussion et se passant comme cible.

Dans la plupart des cas, l'interface Runnable doit être utilisé si vous ne prévoyez de passer outre la méthode de run() et aucune autre méthode de discussion. Ceci est important parce que les classes ne doivent pas être sous-entend moins que le programmeur sur la modification ou l'amélioration du comportement fondamental de la classe.

Quand il est nécessaire d'étendre une superclasse, qui implémente l'interface Runnable est plus approprié que d'utiliser la classe Thread. Parce que nous pouvons étendre une autre classe tout en implémentant l'interface Runnable pour faire un fil.

J'espère que cela vous aidera!

Une chose que je suis surpris n'a pas été encore mentionné est que la mise en œuvre Runnable rend votre classe plus flexible.

Si vous étendez fil alors l'action que vous faites va toujours être dans un fil. Cependant, si vous implémentez Runnable il ne doit pas être. Vous pouvez l'exécuter dans un thread, ou passer à une sorte de service exécuteur testamentaire, ou tout simplement passer autour comme une tâche au sein d'une seule application filetée (peut-être être exécuté à une date ultérieure, mais dans le même fil). Les options sont beaucoup plus ouverts si vous utilisez seulement Runnable que si vous vous engagez à Thread.

Si vous voulez ou met en œuvre Prolonge toute autre classe alors interface Runnable est plus préférable, sinon, si vous ne voulez pas une autre classe pour étendre ou mettre en œuvre alors Thread classe est préférable.

La différence la plus commune est

entrer image description ici

Lorsque vous extends Thread la classe, après que vous ne pouvez pas étendre une autre classe que vous devez. (Comme vous le savez, Java ne permet pas hériter de plus d'une classe).

Lorsque vous implements Runnable, vous pouvez économiser de l'espace pour votre classe d'étendre toute autre classe à l'avenir ou maintenant.

  • Java ne supporte pas les héritages multiples, ce qui signifie que vous ne pouvez étendre une classe en Java donc une fois que vous avez étendu classe Thread vous avez perdu votre chance et ne peut pas étendre ou hériter une autre classe en Java.

  • Dans la programmation orientée objet, l'extension d'une classe signifie généralement, en ajoutant de nouvelles fonctionnalités, et de modifier ou d'améliorer les comportements. Si nous ne faisons aucune modification sur un fil, puis utilisez plutôt l'interface Runnable.

  • interface Runnable représente un groupe qui peut être exécuté soit par simple fil ou exécuteurs ou tout autre moyen. si la séparation logique de tâche Runnable que cette discussion est une bonne décision de conception.

  • La séparation tâche Runnable signifie que nous pouvons réutiliser la tâche et a également la liberté de l'exécuter à partir de moyens différents. puisque vous ne pouvez pas redémarrer un thread une fois qu'il est terminé. nouveau Runnable vs discussion pour la tâche, est Runnable gagnant.

  • Java Designer reconnaît et c'est pourquoi accepter Huissiers Runnable comme la tâche et ils ont thread de travail qui exécute les tâches.

  • Hériter toutes les méthodes de discussion sont les frais généraux supplémentaires juste pour représenter une tâche qui peut être fait facilement avec Runnable.

Avec l'aimable autorisation de javarevisited.blogspot.com

Ce sont quelques-unes des différences notables entre cette discussion et Runnable en Java. Si vous connaissez d'autres différences sur cette discussion vs Runnable que s'il vous plaît le partager via les commentaires. Personnellement, j'utilise Runnable sur fil pour ce scénario et recommande d'utiliser l'interface Runnable ou rachetable en fonction de vos besoins.

, la différence significative est toutefois.

Lorsque vous extends Thread classe, chacun de votre fil crée un objet unique et associer. Lorsque vous implements Runnable, il partage le même objet à plusieurs threads.

En fait, il n'est pas sage de comparer Runnable et Thread les uns avec les autres.

deux ont une dépendance et des relations dans le multi-threading comme la relation Wheel and Engine de véhicule à moteur.

Je dirais, il n'y a qu'un seul moyen pour le multi-threading avec deux étapes. Permettez-moi de faire mon point.

Runnable: Lors de la mise en œuvre interface Runnable cela signifie que vous créez quelque chose qui est run able dans un autre thread. Maintenant, créer quelque chose qui peut courir à l'intérieur d'un fil (un fil à l'intérieur runnable), ne signifie pas la création d'un fil.
Ainsi, la MyRunnable de classe est rien mais une classe ordinaire avec une méthode de void run. Et il est des objets seront des objets ordinaires avec seulement une run méthode qui exécutera normalement lorsqu'il est appelé. (À moins que nous passons l'objet dans un thread).

Discussion: class Thread, je dirais Une classe très spéciale avec la capacité de lancer un nouveau fil qui permet en fait multi-threading par sa méthode start().

Pourquoi ne 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:

  • Quelque chose qui peut fonctionner dans un fil (Runnable).
  • Quelque chose qui peut commencer une nouvelle discussion (thread).

Ainsi, techniquement et théoriquement les deux est nécessaire de commencer un fil, on run et on faire tourner (comme Wheel and Engine de véhicule à moteur).

C'est pourquoi vous ne pouvez pas démarrer un thread avec MyRunnable vous devez passer à une instance de Thread.

Mais il est possible de créer et exécuter un seul fil en utilisant class Thread parce Thread de classe implémente Runnable donc nous savons tous Thread est aussi un Runnable intérieur.

Enfin Thread et Runnable sont complément les uns aux autres pour le multithreading non concurrent ou remplacement.

Vous devez implémenter Runnable, mais si vous exécutez sur Java 5 ou plus, vous ne devriez pas commencer avec new Thread mais utiliser ExecutorService à la place. Pour plus de détails voir:. Comment implémenter enfilage simple Java

Je ne suis pas un expert, mais je ne peux penser à une raison de mettre en œuvre Runnable au lieu de prolonger cette discussion:. Java ne supporte que l'héritage unique, de sorte que vous ne pouvez étendre une classe

Edit: Ceci dit à l'origine « La mise en œuvre d'une interface nécessite moins de ressources. » ainsi, mais vous devez créer une nouvelle instance de discussion de toute façon, donc ce trompais.

Je dirais qu'il ya une troisième voie:

public class Something {

    public void justAnotherMethod() { ... }

}

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

Peut-être cela est influencé un peu par ma récente utilisation intensive de Javascript et Actionscript 3, mais cette façon votre classe n'a pas besoin d'implémenter une interface assez vague comme Runnable.

Avec la sortie de Java 8, il y a maintenant une troisième option.

Runnable est une interface de href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8"> fonctionnelle , qui signifie que les instances de celui-ci peuvent être créés avec des expressions lambda ou des références de la méthode.

Votre exemple peut être remplacé par:

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

ou si vous voulez utiliser un ExecutorService et une référence de méthode:

executor.execute(runner::run)

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 Runnable sur Thread, tels que la responsabilité unique et la composition à l'aide parce que vous n'êtes pas spécialisé le comportement du fil. De cette façon, évite également de créer une classe supplémentaire si vous avez besoin est un Runnable comme vous le faites dans vos exemples.

instanciation une interface donne une séparation plus propre entre votre code et la mise en œuvre de fils, donc je préfère mettre en œuvre Runnable dans ce cas.

Tout le monde ici semble penser que la mise en œuvre est Runnable la voie à suivre et je ne suis pas en désaccord vraiment avec eux, mais il y a aussi un cas pour l'extension de cette discussion, à mon avis, en fait, vous avez démontré qu'il sorte de votre code.

Si vous implémentez Runnable alors la classe qui implémente Runnable n'a aucun contrôle sur le nom du fil, il est le code d'appel qui peut définir le nom du fil, comme suit:

new Thread(myRunnable,"WhateverNameiFeelLike");

mais si vous étendez cette discussion vous obtenez de gérer cela dans la classe elle-même (comme dans votre exemple, vous nommez le fil « ThreadB »). Dans ce cas, vous:

A) peut lui donner un nom plus utile pour le débogage

B) contraignent que ce nom soit utilisé pour toutes les instances de cette classe (sauf si vous ignorez le fait qu'il est un fil et faites ci-dessus avec elle comme si elle est un Runnable, mais nous parlons de convention ici dans une cas peut donc ignorer cette possibilité, je me sens).

Vous pouvez même prendre par exemple une trace de la pile de sa création et l'utiliser comme nom de fil. Cela peut sembler étrange, mais selon la façon dont votre code est structuré, il peut être très utile pour le débogage.

Cela peut sembler une petite chose, mais où vous avez une application très complexe avec beaucoup de fils et tout d'un coup les choses « ont cessé » (soit pour des raisons de blocage ou peut-être à cause d'un défaut dans un protocole de réseau qui serait moins évident - ou d'autres raisons sans fin), puis obtenir une décharge de la pile de Java où tous les fils sont appelés « thread-1 », « discussion-2 », « thread-3 » est pas toujours très utile (cela dépend de la façon dont vos fils sont structurés et si vous pouvez utilement dire qui est qui vient par leur trace de la pile -. pas toujours possible si vous utilisez des groupes de plusieurs threads en cours d'exécution tous le même code)

Cela dit, vous pouvez bien sûr aussi faire ce qui précède d'une manière générique en créant une extension de la classe de fil qui définit son nom à une trace de la pile de son appel de création et de l'utiliser ensuite avec vos implémentations Runnable au lieu de la norme java classe thread (voir ci-dessous), mais en plus de la trace de la pile il pourrait y avoir plus de contexte des informations spécifiques qui seraient utiles au nom de fil pour le débogage (une référence à l'une des nombreuses files d'attente ou prises, il pourrait le traitement par exemple dans ce cas, vous pourraient préférer étendre cette discussion spécifiquement pour ce cas afin que vous puissiez avoir la force du compilateur vous (ou d'autres en utilisant vos bibliothèques) pour passer dans certaines informations (par exemple, la file d'attente / prise en question) pour une utilisation dans le nom).

Voici un exemple du fil générique avec la trace de pile d'appel comme son nom:

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

et voici un échantillon de la sortie comparant les deux noms:

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 parce que:

  • Feuilles plus de flexibilité pour la la mise en œuvre Runnable pour étendre une autre classe
  • Sépare le code de exécution
  • vous permet d'exécuter votre runnable d'un pool de threads, la thread d'événement, ou de toute autre manière à l'avenir.

Même si vous n'avez pas besoin de cela maintenant, vous pouvez à l'avenir. Comme il n'y a aucun avantage à cette discussion primordiale, est Runnable une meilleure solution.

Comme il est un sujet très populaire et les bonnes réponses sont réparties partout et traitée en profondeur, je me suis senti qu'il est justifié de compiler les bonnes réponses des autres dans une forme plus concise, donc les nouveaux arrivants ont un bon aperçu dès le départ:

  1. Vous prolongez généralement une classe pour ajouter ou modifier la fonctionnalité. Alors, si vous ne voulez pas Ecraser tout comportement de fil , puis utilisez Runnable.

  2. Dans la même veine, si vous n'avez pas besoin Hériter méthodes de fil, vous pouvez le faire sans que frais généraux par en utilisant Runnable.

  3. héritage unique :. Si vous étendez cette discussion vous ne pouvez pas étendre de toute autre classe, donc si c'est ce que vous devez faire, vous devez utiliser Runnable

  4. Il est bon design à la logique de domaine séparé de moyens techniques, en ce sens, il est préférable d'avoir une tâche Runnable isolement tâche de runner .

  5. Vous pouvez execute même Runnable objet plusieurs fois , un objet de discussion, cependant, ne peut démarrer une fois. (Peut-être la raison, pourquoi ne Huissiers acceptent runnables, mais pas les threads).

  6. Si vous développez votre tâche en tant que Runnable, vous avez toute la flexibilité comment l'utiliser maintenant et dans l'avenir . Vous pouvez le faire tourner simultanément via Huissiers mais aussi par fil. Et vous pouvez aussi utiliser encore / appeler non simultanément dans le même fil comme tout autre type ordinaire / objet.

  7. Cela rend également plus facile à séparés tâche logique et concurrency aspects tests unitaires .

  8. Si vous êtes intéressé par cette question, vous pourriez être également intéressé par le différence entre appelable et Exécutable.

La différence entre l'extension de la discussion et la mise en œuvre Runnable sont:

 ici

Ceci est discuté dans les Définition et lancement d'un tutoriel Discussion:

  

Lequel de ces idiomes utiliser? Le premier idiome, qui emploie un   objet Runnable, est plus générale, parce que l'objet peut Runnable   sous-classe d'une autre classe que cette discussion. Le second langage est plus facile à utiliser   dans des applications simples, mais il est limité par le fait que votre tâche   classe doit être un descendant de fil. Cette leçon se concentre sur la première   approche, qui sépare la tâche Runnable de l'objet de cette discussion   qui exécute la tâche. Non seulement cette approche plus souple, mais   il est applicable aux API de gestion des threads de haut niveau couverts   plus tard.

En d'autres termes, la mise en œuvre Runnable fonctionnera dans des scénarios où votre classe étend une classe autre que Thread. Java ne supporte pas l'héritage multiple. En outre, l'extension Thread ne sera pas possible en utilisant certaines des API de gestion des threads de haut niveau. Le seul scénario où Thread extension est préférable est dans une petite application qui ne sera pas soumis à des mises à jour à l'avenir. Il est presque toujours préférable de mettre en œuvre Runnable car il est plus souple que votre projet se développe. Un changement de conception ne sera pas avoir un impact majeur que vous pouvez mettre en œuvre de nombreuses interfaces en Java, mais seulement étendre une classe.

Si je ne me trompe pas, il est plus ou moins semblable à

Quelle est la différence entre une interface et classe abstraite?

étend établit " est un " relation et l'interface fournit " un " capacité.

Préférez implémente Runnable :

  1. Si vous ne disposez pas d'étendre cette discussion classe et modifier la mise en œuvre par défaut API Discussion
  2. Si vous exécutez un feu et oublier commande
  3. Si vous étendez déjà une autre classe

Préférez " extends Thread ":

  1. Si vous devez annuler ces méthodes énumérées à la page de documentation oracle

En général, vous n'avez pas besoin de passer outre le comportement du fil. Alors implémente Runnable est préféré pour la plupart du temps.

Dans un autre, en utilisant ExecutorService avancé ou API ThreadPoolExecutorService fournit plus de flexibilité et de contrôle.

Jetez un oeil à cette question SE:

ExecutorService vs Discussion Casual Spawner

L'explication la plus simple serait par la mise en œuvre Runnable nous pouvons attribuer le même objet à plusieurs threads et chaque partage Thread les mêmes états d'objet et le comportement.

Par exemple, supposons qu'il y a deux fils, thread1 met un nombre entier dans un tableau et thread2 prend des nombres entiers de la matrice lorsque la matrice est remplie vers le haut. Notez que pour thread2 pour travailler, il a besoin de connaître l'état de tableau, si thread1 a rempli ou non.

La mise en œuvre Runnable vous permet d'avoir cette flexibilité pour partager l'objet alors que extends Thread vous permet de créer de nouveaux objets pour chaque threads donc une mise à jour qui se fait par thread1 est perdu à Thread2.

Séparer la classe fil de la mise en œuvre Runnable permet également d'éviter les problèmes potentiels de synchronisation entre le fil et la méthode run (). Une Runnable séparée donne généralement une plus grande flexibilité dans la façon dont le code est référencé runnable et exécuté.

C'est S de SOLID : responsabilité unique.

fil incarne contexte en cours d'exécution (comme dans le contexte d'exécution: cadre de pile, id de fil, etc.) de la exécution asynchrone de un morceau de code. Ce morceau de code devrait idéalement être la même mise en œuvre, que ce soit synchrone ou asynchrone .

Si vous les regrouper en une seule application, vous donnez l'objet résultant de deux sans rapport avec causes du changement:

  1. manipulation de fil dans votre application (ie. Interrogation et modification du contexte d'exécution)
  2. algorithme mis en oeuvre par le morceau de code (la partie exécutable)

Si la langue 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 il se résume à la même que la composition des deux objets, puisque leurs ensembles de fonctionnalités ne se chevauchent pas. C'est la théorie.

Dans la pratique, d'une manière générale, un programme n'a pas besoin de porter une plus grande complexité que nécessaire. Si vous avez un fil de travail sur une tâche spécifique, sans jamais changer cette tâche, il est probablement inutile de faire les tâches des classes séparées, et votre code reste simple.

Dans le contexte de Java , puisque l'installation est déjà , il est probablement plus facile de commencer directement avec les classes de Runnable autonomes, et de transmettre leurs instances à Thread ( ou instances Executor). Une fois que utilisé pour ce modèle, il est plus difficile à utiliser (ou même lire) que le simple cas de fil runnable.

Une raison pour laquelle 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 une classe, mais vous pouvez mettre en œuvre un certain nombre d'interfaces.

Si vous étendez cette discussion, vous empêchez votre logique essentiellement à exécuter par un autre thread que « ceci ». Si vous ne souhaitez que certains thread pour exécuter votre logique, il est préférable de mettre en œuvre tout Runnable.

si vous utilisez runnable vous pouvez enregistrer l'espace pour étendre à toute votre autre classe.

Peut-on revisiter la raison fondamentale que nous voulions que notre classe pour se comporter comme un Thread? Il n'y a aucune raison du tout, nous voulions juste pour exécuter une tâche, très probablement dans un mode asynchrone, ce qui signifie précisément que l'exécution de la tâche doit bifurquer de notre fil conducteur et le fil conducteur se termine tôt, peuvent ou non attendre pour le chemin ramifié (tâche).

Si tel est le but entier, alors où est-ce que je vois la nécessité d'un fil spécialisé. Ceci peut être accompli en ramassant un fil RAW du pool de thread du système et en lui attribuant notre tâche (peut être une instance de notre classe) et est-il.

Alors obéissons le concept OOPs et écrire une classe du type dont nous avons besoin. Il y a plusieurs façons de faire les choses, il fait dans les bonnes questions à sens unique.

Nous avons besoin d'une tâche, donc écrire une définition de tâche qui peut être exécutée sur un thread. Il faut donc utiliser Runnable.

Rappelez-vous toujours implements est spécialement utilisé pour conférer un comportement et extends est utilisé pour conférer une caractéristique / propriété.

Nous ne voulons pas la propriété du fil, à la place que nous voulons que notre classe se comporte comme une tâche qui peut être exécutée.

Oui, Si vous appelez appel ThreadA, alors pas besoin d'appeler la méthode de démarrage et la méthode d'exécution est appel après appel que la classe ThreadA. Mais si l'on utilise l'appel ThreadB alors besoin le fil de démarrage nécessaire pour la méthode d'exécution d'appel. Si vous avez plus d'aide, me répondre.

Je trouve qu'il est plus utile d'utiliser Runnable pour toutes les raisons mentionnées, mais parfois j'aime prolonger cette discussion afin que je puisse créer ma propre méthode d'arrêt du fil et l'appeler directement sur le fil que je l'ai créé.

Java ne supporte pas l'héritage multiple, donc si vous Prolonge classe Thread alors aucune autre classe sera prolongée.

Par exemple: Si vous créez une applet alors il doit étend la classe Applet ici la seule manière façon de créer thread en mettant en œuvre l'interface Runnable

Runnable est une interface, alors que Thread est une classe qui implémente cette interface. D'un 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 il est exécuté. Le premier est la responsabilité d'une mise en œuvre de Runnalbe, et celle-ci est l'emploi de la classe Thread. Dans la plupart des cas, la mise en œuvre Runnable est la bonne façon de suivre.

La différence entre cette discussion et runnable .Si nous créons cette discussion avec la classe puis enfilez Nombre de fil égal à nombre d'objets que nous avons créé. Si nous créons fil en implémentant l'interface runnable alors nous pouvons utiliser seul objet pour créer plusieurs thread.So objet unique est partagé par plusieurs Thread.So il prendra moins de mémoire

Donc, en fonction de l'exigence si nos données ne sont pas senstive. Il peut donc être partagé entre plusieurs Discussion on peut utiliser l'interface Runnable.

Ajout d'ici mes deux cents - Toujours autant que possible l'utilisation implements Runnable. Voici deux mises en garde sur pourquoi vous ne devriez pas utiliser extends Threads

  1. s'étendre Idéalement vous ne devriez jamais la classe Thread; la classe Thread doit être final. Au moins ses méthodes comme thread.getId(). Voir cette discussion pour un bug lié à l'extension Threads.

  2. Ceux qui aiment résoudre des énigmes peut voir un autre effet secondaire de l'extension de fil. Le code ci-dessous imprimera le code inaccessible quand personne ne les avertir.

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 ");
        }
    } 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top