La différence entre les interfaces Runnable et Callable en Java
492
Quelle est la différence entre l'utilisation des interfaces Runnableet Callablelors de la conception d'un thread simultané en Java, pourquoi choisiriez-vous l'une plutôt que l'autre?
L'interface Callable est similaire à Runnable, en ce sens que les deux sont conçues pour les classes dont les instances sont potentiellement exécutées par un autre thread. Un Runnable, cependant, ne renvoie pas de résultat et ne peut pas lever d'exception vérifiée.
Quelles sont les différences dans les applications de Runnableet Callable. La différence est-elle uniquement avec le paramètre de retour présent dans Callable?
Quel est le besoin d'avoir les deux si l' Callableon peut faire tout ce qui Runnablefait?
Parce que l' Runnableinterface ne peut pas tout faire Callable!
Runnableexiste depuis Java 1.0, mais Callablen'a été introduit que dans Java 1.5 ... pour gérer les cas d'utilisation qui Runnablene sont pas pris en charge. En théorie, l'équipe Java aurait pu changer la signature de la Runnable.run()méthode, mais cela aurait rompu la compatibilité binaire avec le code antérieur à 1.5, nécessitant un recodage lors de la migration de l'ancien code Java vers des machines virtuelles Java plus récentes. C'est un GRAND NON-NON. Java s'efforce d'être rétrocompatible ... et c'est l'un des principaux arguments de vente de Java pour l'informatique d'entreprise.
Et, évidemment, il existe des cas d'utilisation où une tâche n'a pas besoin de retourner un résultat ou de lever une exception vérifiée. Pour ces cas d'utilisation, l'utilisation Runnableest plus concise que l'utilisation Callable<Void>et le retour d'une nullvaleur fictive ( ) à partir de la call()méthode.
Je me demande d'où vous est venue cette histoire. C'est très utile.
spiderman
4
@prash - les faits de base se trouvent dans les anciens manuels. Comme la première édition de Java in a Nutshell.
Stephen C
4
(@prash - Aussi ... en commençant à utiliser Java à l'ère de Java 1.1.)
Stephen C
1
@StephenC Si j'ai bien lu votre réponse, vous suggérez qu'elle Runnableexiste (en grande partie) pour des raisons de compatibilité descendante. Mais n'y a-t-il pas des situations où il est inutile ou trop coûteux d'implémenter (ou d'exiger) une Callableinterface (par exemple, en ScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit))? N'y a-t-il donc aucun avantage à maintenir les deux interfaces dans le langage, même si l'histoire n'a pas forcé le résultat actuel?
max
1
@max - Eh bien, je l'ai dit et je suis toujours d'accord avec cela. Cependant, c'est une raison secondaire. Mais même ainsi, je soupçonne que Runnablecela aurait été modifié s'il n'y avait pas eu impératif de maintenir la compatibilité. Le «passe-partout» de return null;est un argument faible. (Au moins, cela aurait été ma décision ... dans le contexte hypothétique où vous pourriez ignorer la compatibilité descendante.)
Stephen C
82
Un Callabledoit implémenter une call()méthode tandis qu'un a Runnablebesoin d'implémenter une run()méthode.
A Callablepeut renvoyer une valeur mais Runnablepas.
Un Callablepeut lever l'exception vérifiée mais Runnablepas.
A Callablepeut être utilisé avec des ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)méthodes mais Runnablepas.
publicinterfaceRunnable{void run();}publicinterfaceCallable<V>{
V call()throwsException;}
ExecutorService.submit (tâche exécutable) existe également et est très utile
Yair Kukielka
Runnable peut également être utilisé avec ExecutorService de la manière suivante: 1) ExecutorService.execute (Runnable) 2) ExecutorService.submit (Runnable)
Azam Khan
2
Il existe également Executor.submit (tâche Callable <T>) mais vous ne pouvez pas invokeAll ou invokeAny avec la collection de tâches Runnable Collection <? étend les tâches
Callable
36
J'ai trouvé cela dans un autre blog qui peut expliquer un peu plus ces différences :
Bien que les deux interfaces soient implémentées par les classes qui souhaitent s'exécuter dans un thread d'exécution différent, mais il y a peu de différences entre les deux interfaces qui sont:
Une Callable<V>instance renvoie un résultat de type V, contrairement à une Runnableinstance.
Une Callable<V>instance peut lever des exceptions vérifiées, tandis qu'une Runnableinstance ne peut pas
Les concepteurs de Java ont ressenti le besoin d'étendre les capacités de l' Runnableinterface, mais ils ne voulaient pas affecter les utilisations de l' Runnableinterface et c'est probablement la raison pour laquelle ils ont opté pour une interface distincte nommée Callabledans Java 1.5 plutôt que de changer la déjà existant Runnable.
Voyons où l'on pourrait utiliser Runnable et Callable.
Runnable et Callable s'exécutent tous les deux sur un thread différent du thread appelant. Mais Callable peut renvoyer une valeur et Runnable ne le peut pas. Alors, où cela s'applique-t-il vraiment?
Runnable : Si vous avez un feu et oubliez la tâche, utilisez Runnable. Placez votre code dans un Runnable et lorsque la méthode run () est appelée, vous pouvez effectuer votre tâche. Le thread appelant ne se soucie vraiment pas lorsque vous effectuez votre tâche.
Callable : Si vous essayez de récupérer une valeur d'une tâche, utilisez Callable. Désormais appelable seul, il ne fera pas l'affaire. Vous aurez besoin d'un Futur que vous enroulerez autour de votre Callable et obtiendrez vos valeurs sur future.get (). Ici, le thread appelant sera bloqué jusqu'à ce que le futur revienne avec des résultats qui à leur tour attendent l'exécution de la méthode call () de Callable.
Pensez donc à une interface vers une classe cible dans laquelle vous avez défini à la fois des méthodes encapsulées Runnable et Callable. La classe appelante appellera aléatoirement vos méthodes d'interface sans savoir laquelle est Runnable et laquelle est Callable. Les méthodes Runnable s'exécuteront de manière asynchrone, jusqu'à ce qu'une méthode Callable soit appelée. Ici, le thread de la classe appelante se bloquera car vous récupérez des valeurs de votre classe cible.
REMARQUE: à l'intérieur de votre classe cible, vous pouvez effectuer les appels à Callable et Runnable sur un exécuteur de thread unique, ce qui rend ce mécanisme similaire à une file d'attente de répartition en série. Donc, tant que l'appelant appelle vos méthodes encapsulées Runnable, le thread appelant s'exécutera très rapidement sans blocage. Dès qu'il appelle une méthode Callable enveloppée dans Future, il devra bloquer jusqu'à ce que tous les autres éléments en file d'attente soient exécutés. Ce n'est qu'alors que la méthode renverra des valeurs. Il s'agit d'un mécanisme de synchronisation.
Callablel'interface déclare la call()méthode et vous devez fournir des génériques comme type d'appel Object () devrait retourner -
publicinterfaceCallable<V>{/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call()throwsException;}
Runnabled'autre part, est l'interface qui déclare la run()méthode qui est appelée lorsque vous créez un thread avec runnable et appelez start () dessus. Vous pouvez également appeler directement run () mais qui exécute simplement la méthode run () est le même thread.
publicinterfaceRunnable{/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/publicabstractvoid run();}
Pour résumer, quelques différences notables sont
Un Runnableobjet ne renvoie pas de résultat alors qu'un Callableobjet renvoie un résultat.
Un Runnableobjet ne peut pas lever d'exception vérifiée alors qu'un Callableobjet peut lever une exception.
L' Runnableinterface existe depuis Java 1.0 alors qu'elle Callablen'a été introduite que dans Java 1.5.
Peu de similitudes comprennent
Les instances des classes qui implémentent des interfaces Runnable ou Callable sont potentiellement exécutées par un autre thread.
L'instance des interfaces Callable et Runnable peut être exécutée par ExecutorService via la méthode submit ().
Les deux sont des interfaces fonctionnelles et peuvent être utilisées dans les expressions Lambda depuis Java8.
Les méthodes de l'interface ExecutorService sont
<T>Future<T> submit(Callable<T> task);Future<?> submit(Runnable task);<T>Future<T> submit(Runnable task, T result);
Objectif de ces interfaces à partir de la documentation Oracle:
L' interface exécutable doit être implémentée par n'importe quelle classe dont les instances sont destinées à être exécutées par a Thread. La classe doit définir une méthode sans arguments appelés run.
Callable : tâche qui renvoie un résultat et peut lever une exception. Les implémenteurs définissent une méthode unique sans argument appelé appel. L' Callableinterface est similaire à Runnable, car les deux sont conçues pour les classes dont les instances sont potentiellement exécutées par un autre thread. A Runnable, cependant, ne renvoie pas de résultat et ne peut pas lever d'exception vérifiée.
Autres différences:
Vous pouvez passer Runnablepour créer un fil . Mais vous ne pouvez pas créer de nouveau Thread en passant Callablecomme paramètre. Vous ne pouvez transmettre Callable qu'aux ExecutorServiceinstances.
publicclassHelloRunnableimplementsRunnable{publicvoid run(){System.out.println("Hello from a thread!");}publicstaticvoid main(String args[]){(newThread(newHelloRunnable())).start();}}
Utilisez Runnablepour le feu et oubliez les appels. Utilisez Callablepour vérifier le résultat.
Callablepeut être passé à la méthode invokeAll contrairement Runnable. Méthodes invokeAnyet invokeAllexécution des formes d'exécution en masse les plus couramment utilisées, exécution d'une collection de tâches, puis attente d'au moins une, ou de toutes, pour terminer
Différence triviale: nom de la méthode à implémenter => run()pour Runnableet call()pour Callable.
Comme il a déjà été mentionné ici, Callable est une interface relativement nouvelle et elle a été introduite dans le cadre du package de concurrence. Callable et Runnable peuvent être utilisés avec des exécuteurs. Le thread de classe (qui implémente Runnable lui-même) ne prend en charge que Runnable.
Vous pouvez toujours utiliser Runnable avec des exécuteurs. L'avantage de Callable que vous pouvez l'envoyer à l'exécuteur testamentaire et récupérer immédiatement le résultat futur qui sera mis à jour lorsque l'exécution sera terminée. La même chose peut être implémentée avec Runnable, mais dans ce cas, vous devez gérer les résultats vous-même. Par exemple, vous pouvez créer une file d'attente de résultats qui contiendra tous les résultats. Un autre thread peut attendre dans cette file d'attente et gérer les résultats qui arrivent.
Je me demande quel est l'exemple d'une exception de lancement de thread en Java? le thread principal pourra-t-il intercepter cette exception? Sinon, je n'utiliserais pas Callable. Alex, avez-vous un aperçu de cela? Merci!
billions
1
Le code s'exécutant dans un thread personnalisé comme tout autre code peut lever l'exception. Pour l'attraper dans un autre thread, vous devez effectuer certains efforts soit en utilisant un mécanisme de notification personnalisé (par exemple basé sur des écouteurs), soit en utilisant Futureou en ajoutant un crochet qui intercepte toutes les exceptions non identifiées
AlexR
Grande info! Merci, Alex! :)
billions
1
J'ai voté pour cette réponse car elle affirme (correctement si elle est prise à sa valeur nominale) que l'on doit utiliser le modèle de pool de threads avec des objets appelables. La chose apparemment malheureuse à ce sujet est que l'on ne peut pas s'étendre Threadpour faire un usage significatif de l' Callableinterface afin qu'un seul thread puisse être personnalisé pour faire des choses appelables et d'autres choses que le développeur pourrait vouloir. Si quelqu'un qui lit ce commentaire pense que je me trompe, j'aimerais mieux savoir ...
8
+-------------------------------------+--------------------------------------------------------------------------------------------------+|Runnable|Callable<T>|+-------------------------------------+--------------------------------------------------------------------------------------------------+|Introduced in Java1.0 of java.lang |Introduced in Java1.5 of java.util.concurrent library ||Runnable cannot be parametrized |Callable is a parametrized type whose type parameter indicates the return type of its run method ||Runnable has run() method |Callable has call() method ||Runnable.run() returns void|Callable.call() returns a value of Type T ||Can not throwCheckedExceptions|CanthrowCheckedExceptions|+-------------------------------------+--------------------------------------------------------------------------------------------------+
Les concepteurs de Java ont ressenti le besoin d'étendre les capacités de l' Runnableinterface, mais ils ne voulaient pas affecter les utilisations de l' Runnableinterface et c'est probablement la raison pour laquelle ils ont opté pour une interface distincte nommée Callabledans Java 1.5 plutôt que de changer la déjà Runnableinterface existante qui fait partie de Java depuis Java 1.0. la source
Les différences entre Callable et Runnable sont les suivantes:
Callable est introduit dans JDK 5.0 mais Runnable est introduit dans JDK 1.0
Callable a la méthode call () mais Runnable a la méthode run ().
Callable a une méthode d'appel qui renvoie une valeur mais Runnable a une méthode d'exécution qui ne renvoie aucune valeur.
la méthode d'appel peut lever l'exception vérifiée mais la méthode d'exécution ne peut pas lever l'exception vérifiée.
Appelable utilise la méthode submit () pour placer dans la file d'attente des tâches mais Runnable utilise la méthode execute () pour placer dans la file d'attente des tâches.
Il est important de souligner que l' exception vérifiée , pas l' exception RuntimeException
BertKing
5
Callable et Runnable sont tous deux similaires et peuvent être utilisés pour implémenter le thread. En cas d'implémentation de Runnable, vous devez implémenter la méthode run () , mais en cas d' appel, vous devez implémenter la méthode call () , les deux méthodes fonctionnent de manière similaire, mais la méthode callable call () a plus de flexibilité.Il y a quelques différences entre elles.
Différence entre Runnable et callable comme ci-dessous -
1) La méthode run () de runnable renvoie void , signifie que si vous voulez que votre thread retourne quelque chose que vous pouvez utiliser plus loin, vous n'avez pas le choix avec la méthode runnable run () . Il existe une solution «Callable» , si vous voulez renvoyer quelque chose sous forme d' objet, vous devez utiliser Callable au lieu de Runnable . L'interface appelable a la méthode 'call ()' qui retourne Object .
Signature de méthode - Runnable->
publicvoid run(){}
Appelable->
publicObject call(){}
2) Dans le cas de la méthode runnable run () si une exception vérifiée survient, vous devez alors gérer avec le bloc try catch , mais dans le cas de la méthode Callable call () , vous pouvez lever l'exception vérifiée comme ci-dessous
publicObject call()throwsException{}
3) Runnable provient de la version java 1.0 héritée , mais callable est venu en version Java 1.5 avec le cadre Executer .
Si vous connaissez les exécuteurs, vous devez utiliser Callable au lieu de Runnable .
Runnable (vs) Callable entre en jeu lorsque nous utilisons le framework Executer.
ExecutorService est une sous-interface de Executor, qui accepte les tâches exécutables et appelables.
Le multi-threading antérieur peut être réalisé à l'aide de l'interface depuis la version 1.0 , mais ici, le problème est qu'après avoir terminé la tâche de thread, nous ne sommes pas en mesure de collecter les informations sur les threads. Afin de collecter les données, nous pouvons utiliser des champs statiques.Runnable
Exemple Fils de discussion séparés pour collecter les données de chaque élève.
staticHashMap<String,List> multiTasksData =newHashMap();publicstaticvoid main(String[] args){Thread t1 =newThread(newRunnableImpl(1),"T1");Thread t2 =newThread(newRunnableImpl(2),"T2");Thread t3 =newThread(newRunnableImpl(3),"T3");
multiTasksData.put("T1",newArrayList());// later get the value and update it.
multiTasksData.put("T2",newArrayList());
multiTasksData.put("T3",newArrayList());}
Pour résoudre ce problème, ils ont introduit la version 1.5 qui renvoie un résultat et peut lever une exception.Callable<V>
Méthode abstraite unique : l'interface Callable et Runnable ont une seule méthode abstraite, ce qui signifie qu'elles peuvent être utilisées dans les expressions lambda en java 8.
Réponses:
Voir l'explication ici .
la source
Fondamentalement, oui. Voir les réponses à cette question . Et le javadoc pour
Callable
.Parce que l'
Runnable
interface ne peut pas tout faireCallable
!Runnable
existe depuis Java 1.0, maisCallable
n'a été introduit que dans Java 1.5 ... pour gérer les cas d'utilisation quiRunnable
ne sont pas pris en charge. En théorie, l'équipe Java aurait pu changer la signature de laRunnable.run()
méthode, mais cela aurait rompu la compatibilité binaire avec le code antérieur à 1.5, nécessitant un recodage lors de la migration de l'ancien code Java vers des machines virtuelles Java plus récentes. C'est un GRAND NON-NON. Java s'efforce d'être rétrocompatible ... et c'est l'un des principaux arguments de vente de Java pour l'informatique d'entreprise.Et, évidemment, il existe des cas d'utilisation où une tâche n'a pas besoin de retourner un résultat ou de lever une exception vérifiée. Pour ces cas d'utilisation, l'utilisation
Runnable
est plus concise que l'utilisationCallable<Void>
et le retour d'unenull
valeur fictive ( ) à partir de lacall()
méthode.la source
Runnable
existe (en grande partie) pour des raisons de compatibilité descendante. Mais n'y a-t-il pas des situations où il est inutile ou trop coûteux d'implémenter (ou d'exiger) uneCallable
interface (par exemple, enScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)
)? N'y a-t-il donc aucun avantage à maintenir les deux interfaces dans le langage, même si l'histoire n'a pas forcé le résultat actuel?Runnable
cela aurait été modifié s'il n'y avait pas eu impératif de maintenir la compatibilité. Le «passe-partout» dereturn null;
est un argument faible. (Au moins, cela aurait été ma décision ... dans le contexte hypothétique où vous pourriez ignorer la compatibilité descendante.)Callable
doit implémenter unecall()
méthode tandis qu'un aRunnable
besoin d'implémenter unerun()
méthode.Callable
peut renvoyer une valeur maisRunnable
pas.Callable
peut lever l'exception vérifiée maisRunnable
pas.A
Callable
peut être utilisé avec desExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)
méthodes maisRunnable
pas.la source
J'ai trouvé cela dans un autre blog qui peut expliquer un peu plus ces différences :
Bien que les deux interfaces soient implémentées par les classes qui souhaitent s'exécuter dans un thread d'exécution différent, mais il y a peu de différences entre les deux interfaces qui sont:
Callable<V>
instance renvoie un résultat de typeV
, contrairement à uneRunnable
instance.Callable<V>
instance peut lever des exceptions vérifiées, tandis qu'uneRunnable
instance ne peut pasLes concepteurs de Java ont ressenti le besoin d'étendre les capacités de l'
Runnable
interface, mais ils ne voulaient pas affecter les utilisations de l'Runnable
interface et c'est probablement la raison pour laquelle ils ont opté pour une interface distincte nomméeCallable
dans Java 1.5 plutôt que de changer la déjà existantRunnable
.la source
Voyons où l'on pourrait utiliser Runnable et Callable.
Runnable et Callable s'exécutent tous les deux sur un thread différent du thread appelant. Mais Callable peut renvoyer une valeur et Runnable ne le peut pas. Alors, où cela s'applique-t-il vraiment?
Runnable : Si vous avez un feu et oubliez la tâche, utilisez Runnable. Placez votre code dans un Runnable et lorsque la méthode run () est appelée, vous pouvez effectuer votre tâche. Le thread appelant ne se soucie vraiment pas lorsque vous effectuez votre tâche.
Callable : Si vous essayez de récupérer une valeur d'une tâche, utilisez Callable. Désormais appelable seul, il ne fera pas l'affaire. Vous aurez besoin d'un Futur que vous enroulerez autour de votre Callable et obtiendrez vos valeurs sur future.get (). Ici, le thread appelant sera bloqué jusqu'à ce que le futur revienne avec des résultats qui à leur tour attendent l'exécution de la méthode call () de Callable.
Pensez donc à une interface vers une classe cible dans laquelle vous avez défini à la fois des méthodes encapsulées Runnable et Callable. La classe appelante appellera aléatoirement vos méthodes d'interface sans savoir laquelle est Runnable et laquelle est Callable. Les méthodes Runnable s'exécuteront de manière asynchrone, jusqu'à ce qu'une méthode Callable soit appelée. Ici, le thread de la classe appelante se bloquera car vous récupérez des valeurs de votre classe cible.
REMARQUE: à l'intérieur de votre classe cible, vous pouvez effectuer les appels à Callable et Runnable sur un exécuteur de thread unique, ce qui rend ce mécanisme similaire à une file d'attente de répartition en série. Donc, tant que l'appelant appelle vos méthodes encapsulées Runnable, le thread appelant s'exécutera très rapidement sans blocage. Dès qu'il appelle une méthode Callable enveloppée dans Future, il devra bloquer jusqu'à ce que tous les autres éléments en file d'attente soient exécutés. Ce n'est qu'alors que la méthode renverra des valeurs. Il s'agit d'un mécanisme de synchronisation.
la source
Callable
l'interface déclare lacall()
méthode et vous devez fournir des génériques comme type d'appel Object () devrait retourner -Runnable
d'autre part, est l'interface qui déclare larun()
méthode qui est appelée lorsque vous créez un thread avec runnable et appelez start () dessus. Vous pouvez également appeler directement run () mais qui exécute simplement la méthode run () est le même thread.Pour résumer, quelques différences notables sont
Runnable
objet ne renvoie pas de résultat alors qu'unCallable
objet renvoie un résultat.Runnable
objet ne peut pas lever d'exception vérifiée alors qu'unCallable
objet peut lever une exception.Runnable
interface existe depuis Java 1.0 alors qu'elleCallable
n'a été introduite que dans Java 1.5.Peu de similitudes comprennent
Les méthodes de l'interface ExecutorService sont
la source
Objectif de ces interfaces à partir de la documentation Oracle:
L' interface exécutable doit être implémentée par n'importe quelle classe dont les instances sont destinées à être exécutées par a
Thread
. La classe doit définir une méthode sans arguments appelésrun
.Callable : tâche qui renvoie un résultat et peut lever une exception. Les implémenteurs définissent une méthode unique sans argument appelé appel. L'
Callable
interface est similaire àRunnable
, car les deux sont conçues pour les classes dont les instances sont potentiellement exécutées par un autre thread. ARunnable
, cependant, ne renvoie pas de résultat et ne peut pas lever d'exception vérifiée.Autres différences:
Vous pouvez passer
Runnable
pour créer un fil . Mais vous ne pouvez pas créer de nouveau Thread en passantCallable
comme paramètre. Vous ne pouvez transmettre Callable qu'auxExecutorService
instances.Exemple:
Utilisez
Runnable
pour le feu et oubliez les appels. UtilisezCallable
pour vérifier le résultat.Callable
peut être passé à la méthode invokeAll contrairementRunnable
. MéthodesinvokeAny
etinvokeAll
exécution des formes d'exécution en masse les plus couramment utilisées, exécution d'une collection de tâches, puis attente d'au moins une, ou de toutes, pour terminerDifférence triviale: nom de la méthode à implémenter =>
run()
pourRunnable
etcall()
pourCallable
.la source
Comme il a déjà été mentionné ici, Callable est une interface relativement nouvelle et elle a été introduite dans le cadre du package de concurrence. Callable et Runnable peuvent être utilisés avec des exécuteurs. Le thread de classe (qui implémente Runnable lui-même) ne prend en charge que Runnable.
Vous pouvez toujours utiliser Runnable avec des exécuteurs. L'avantage de Callable que vous pouvez l'envoyer à l'exécuteur testamentaire et récupérer immédiatement le résultat futur qui sera mis à jour lorsque l'exécution sera terminée. La même chose peut être implémentée avec Runnable, mais dans ce cas, vous devez gérer les résultats vous-même. Par exemple, vous pouvez créer une file d'attente de résultats qui contiendra tous les résultats. Un autre thread peut attendre dans cette file d'attente et gérer les résultats qui arrivent.
la source
Future
ou en ajoutant un crochet qui intercepte toutes les exceptions non identifiéesThread
pour faire un usage significatif de l'Callable
interface afin qu'un seul thread puisse être personnalisé pour faire des choses appelables et d'autres choses que le développeur pourrait vouloir. Si quelqu'un qui lit ce commentaire pense que je me trompe, j'aimerais mieux savoir ...Les concepteurs de Java ont ressenti le besoin d'étendre les capacités de l'
Runnable
interface, mais ils ne voulaient pas affecter les utilisations de l'Runnable
interface et c'est probablement la raison pour laquelle ils ont opté pour une interface distincte nomméeCallable
dans Java 1.5 plutôt que de changer la déjàRunnable
interface existante qui fait partie de Java depuis Java 1.0. la sourcela source
Les différences entre Callable et Runnable sont les suivantes:
la source
Callable et Runnable sont tous deux similaires et peuvent être utilisés pour implémenter le thread. En cas d'implémentation de Runnable, vous devez implémenter la méthode run () , mais en cas d' appel, vous devez implémenter la méthode call () , les deux méthodes fonctionnent de manière similaire, mais la méthode callable call () a plus de flexibilité.Il y a quelques différences entre elles.
Différence entre Runnable et callable comme ci-dessous -
1) La méthode run () de runnable renvoie void , signifie que si vous voulez que votre thread retourne quelque chose que vous pouvez utiliser plus loin, vous n'avez pas le choix avec la méthode runnable run () . Il existe une solution «Callable» , si vous voulez renvoyer quelque chose sous forme d' objet, vous devez utiliser Callable au lieu de Runnable . L'interface appelable a la méthode 'call ()' qui retourne Object .
Signature de méthode - Runnable->
Appelable->
2) Dans le cas de la méthode runnable run () si une exception vérifiée survient, vous devez alors gérer avec le bloc try catch , mais dans le cas de la méthode Callable call () , vous pouvez lever l'exception vérifiée comme ci-dessous
3) Runnable provient de la version java 1.0 héritée , mais callable est venu en version Java 1.5 avec le cadre Executer .
Si vous connaissez les exécuteurs, vous devez utiliser Callable au lieu de Runnable .
J'espère que tu as compris.
la source
Runnable (vs) Callable entre en jeu lorsque nous utilisons le framework Executer.
ExecutorService est une sous-interface de
Executor
, qui accepte les tâches exécutables et appelables.Le multi-threading antérieur peut être réalisé à l'aide de l'interface depuis la version 1.0 , mais ici, le problème est qu'après avoir terminé la tâche de thread, nous ne sommes pas en mesure de collecter les informations sur les threads. Afin de collecter les données, nous pouvons utiliser des champs statiques.
Runnable
Exemple Fils de discussion séparés pour collecter les données de chaque élève.
Pour résoudre ce problème, ils ont introduit la version 1.5 qui renvoie un résultat et peut lever une exception.
Callable<V>
Méthode abstraite unique : l'interface Callable et Runnable ont une seule méthode abstraite, ce qui signifie qu'elles peuvent être utilisées dans les expressions lambda en java 8.
Il existe différentes manières de déléguer des tâches pour exécution à un ExecutorService .
execute(Runnable task):void
crée un nouveau thread mais ne bloque pas le thread principal ou le thread appelant car cette méthode retourne void.submit(Callable<?>):Future<?>
,submit(Runnable):Future<?>
crée un nouveau thread et bloque le thread principal lorsque vous utilisez future.get () .Exemple d'utilisation d'interfaces exécutables, appelables avec le framework Executor.
la source
C'est une sorte de convention de dénomination d'interface qui correspond à la programmation fonctionnelle
la source