A diferença entre as interfaces Runnable e Callable em Java
492
Qual é a diferença entre usar as interfaces Runnablee Callableao projetar um encadeamento simultâneo em Java, por que você escolheria um sobre o outro?
A interface Callable é semelhante ao Runnable, pois ambas são projetadas para classes cujas instâncias são potencialmente executadas por outro thread. Um Runnable, no entanto, não retorna um resultado e não pode gerar uma exceção verificada.
Qual é a necessidade de ter os dois se Callablepode fazer tudo o que Runnablefaz?
Porque a Runnableinterface não pode fazer tudo o que Callablefaz!
Runnableexiste desde o Java 1.0, mas Callablefoi introduzido apenas no Java 1.5 ... para lidar com casos de uso que Runnablenão suportam. Em teoria, a equipe Java poderia ter alterado a assinatura do Runnable.run()método, mas isso quebraria a compatibilidade binária com o código anterior à 1.5, exigindo recodificação ao migrar o código Java antigo para as JVMs mais recentes. Isso é um GRANDE NÃO-NÃO. O Java se esforça para ser compatível com versões anteriores ... e esse tem sido um dos maiores pontos de venda do Java para computação comercial.
E, obviamente, existem casos de uso em que uma tarefa não precisa retornar um resultado ou lançar uma exceção verificada. Para esses casos de uso, usar Runnableé mais conciso do que usar Callable<Void>e retornar um nullvalor dummy ( ) do call()método
Eu me pergunto de onde você tirou essa história. Isso é muito útil.
spiderman
4
@prash - os fatos básicos podem ser encontrados em livros antigos. Como a primeira edição do Java em poucas palavras.
Stephen C
4
(@prash -. Também ... começando a usar Java na era Java 1.1)
Stephen C
1
@StephenC Se eu li sua resposta corretamente, você está sugerindo que ela Runnableexiste (em grande parte) por motivos de compatibilidade com versões anteriores. Mas não há situações em que é desnecessário ou muito caro implementar (ou exigir) Callableinterface (por exemplo, in ScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit))? Portanto, não há um benefício em manter as duas interfaces no idioma, mesmo que a história não force o resultado atual?
max
1
@max - Bem, eu disse isso, e ainda concordo com isso. No entanto, essa é uma razão secundária. Mas, mesmo assim, suspeito que Runnableteria sido modificado se não houvesse um imperativo para manter a compatibilidade. O "clichê" de return null;é um argumento fraco. (Pelo menos, essa teria sido a minha decisão ... no contexto hipotético onde você poderia ignorar compatibilidade com versões anteriores.)
Stephen C
82
Um Callableprecisa implementar o call()método enquanto outro Runnableprecisa implementar o run()método.
A Callablepode retornar um valor, mas Runnablenão pode.
Um Callablepode lançar exceção marcada, mas um Runnablenão pode.
A Callablepode ser usado com ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)métodos, mas a Runnablenão pode ser.
publicinterfaceRunnable{void run();}publicinterfaceCallable<V>{
V call()throwsException;}
ExecutorService.submit (tarefa executável) também existe e é muito útil
Yair Kukielka 29/05
Executável pode também ser usado com ExecutorService seguindo maneiras-1) ExecutorService.execute (executável) 2) ExecutorService.submit (executável)
Azam Khan
2
Também existe Executor.submit (tarefa Callable <T>), mas você não pode invocarAll ou invokeAny com a coleção de tarefas Runnable Collection <? estende as tarefas Callable <T>>
nikli
36
Encontrei isso em outro blog que pode explicar um pouco mais essas diferenças :
Embora ambas as interfaces sejam implementadas pelas classes que desejam executar em um encadeamento de execução diferente, existem poucas diferenças entre as duas interfaces:
Uma Callable<V>instância retorna um resultado do tipo V, enquanto uma Runnableinstância não.
Uma Callable<V>instância pode gerar exceções verificadas, enquanto uma Runnableinstância não pode
Os designers de Java sentiram a necessidade de estender os recursos da Runnableinterface, mas não queriam afetar os usos da Runnableinterface e provavelmente essa foi a razão pela qual eles optaram por ter uma interface separada nomeada Callableno Java 1.5 do que alterar o já existente Runnable.
Runnable e Callable são executados em um thread diferente do thread de chamada. Mas Callable pode retornar um valor e Runnable não. Então, onde isso realmente se aplica.
Runnable : Se você tiver uma tarefa de ignorar e esquecer, use Runnable. Coloque seu código dentro de um Runnable e, quando o método run () for chamado, você poderá executar sua tarefa. O segmento de chamada realmente não se importa quando você executa sua tarefa.
Chamada : Se você estiver tentando recuperar um valor de uma tarefa, use Chamada. Agora que pode ser chamado por si só não fará o trabalho. Você precisará de um futuro que envolva seu Callable e obtenha seus valores em future.get (). Aqui, o encadeamento de chamada será bloqueado até que o futuro volte com resultados que, por sua vez, aguardam a execução do método call () de Callable.
Portanto, pense em uma interface para uma classe de destino em que você tenha os métodos agrupados Runnable e Callable definidos. A classe de chamada aleatoriamente chamará os métodos da interface sem saber qual é Runnable e qual é Callable. Os métodos Runnable serão executados de forma assíncrona, até que um método Callable seja chamado. Aqui, o encadeamento da classe de chamada será bloqueado, pois você está recuperando valores da sua classe de destino.
NOTA: Dentro da classe de destino, você pode fazer chamadas para Callable e Runnable em um único executor de encadeamento, tornando esse mecanismo semelhante a uma fila de despacho serial. Desde que o chamador chame seus métodos agrupados Runnable, o thread de chamada será executado muito rápido, sem bloquear. Assim que chamar um método Callable envolvido no futuro, ele deverá ser bloqueado até que todos os outros itens na fila sejam executados. Somente então o método retornará com valores. Este é um mecanismo de sincronização.
Callableinterface declara call()método e você precisa fornecer genéricos, pois o tipo de chamada de objeto () deve retornar -
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;}
Runnablepor outro lado, é a interface que declara o run()método chamado quando você cria um Thread com o executável e chama start (). Você também pode chamar diretamente run (), mas que apenas executa o método run () é o mesmo encadeamento.
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();}
Para resumir algumas diferenças notáveis são
Um Runnableobjeto não retorna um resultado, enquanto um Callableobjeto retorna um resultado.
Um Runnableobjeto não pode lançar uma exceção marcada, enquanto um Callableobjeto pode lançar uma exceção.
A Runnableinterface existe desde o Java 1.0, enquanto Callablefoi introduzida apenas no Java 1.5.
Poucas semelhanças incluem
Instâncias das classes que implementam interfaces Runnable ou Callable são potencialmente executadas por outro thread.
A instância das interfaces Callable e Runnable pode ser executada pelo ExecutorService via método submit ().
Ambas são interfaces funcionais e podem ser usadas em expressões Lambda desde o Java8.
Os métodos na interface ExecutorService são
<T>Future<T> submit(Callable<T> task);Future<?> submit(Runnable task);<T>Future<T> submit(Runnable task, T result);
Objetivo dessas interfaces da documentação da Oracle:
A interface executável deve ser implementada por qualquer classe cujas instâncias sejam executadas por a Thread. A classe deve definir um método sem argumentos chamados run.
Callable : uma tarefa que retorna um resultado e pode gerar uma exceção. Os implementadores definem um único método sem argumentos chamados de chamada. A Callableinterface é semelhante Runnable, pois ambas são projetadas para classes cujas instâncias são potencialmente executadas por outro encadeamento. UMARunnable , no entanto, não retorna um resultado e não pode gerar uma exceção verificada.
Outras diferenças:
Você pode passar Runnablepara criar um Thread . Mas você não pode criar um novo thread passando Callablecomo parâmetro. Você pode passar Callable apenas para ExecutorServiceinstâncias.
publicclassHelloRunnableimplementsRunnable{publicvoid run(){System.out.println("Hello from a thread!");}publicstaticvoid main(String args[]){(newThread(newHelloRunnable())).start();}}
Use Runnablepara fogo e esqueça as chamadas. Use Callablepara verificar o resultado.
Callablepode ser passado para invokeAll método diferente Runnable. Métodos invokeAnye invokeAllexecute as formas mais úteis de execução em massa, executando uma coleção de tarefas e aguardando pelo menos uma, ou todas, para concluir
Diferença trivial: nome do método a ser implementado => run()para Runnablee call()para Callable.
Como já foi mencionado aqui, Callable é uma interface relativamente nova e foi introduzida como parte do pacote de simultaneidade. Callable e Runnable podem ser usados com executores. O thread de classe (que implementa o próprio Runnable) oferece suporte apenas ao Runnable.
Você ainda pode usar o Runnable com executores. A vantagem do Callable é que você pode enviá-lo ao executor e retornar imediatamente o resultado futuro que será atualizado quando a execução for concluída. O mesmo pode ser implementado com o Runnable, mas nesse caso você precisa gerenciar os resultados sozinho. Por exemplo, você pode criar uma fila de resultados que conterá todos os resultados. Outro encadeamento pode esperar nessa fila e lidar com os resultados que chegarem.
Gostaria de saber qual é o exemplo em um segmento lançando exceção em java? o thread principal será capaz de capturar essa exceção? Caso contrário, eu não usaria Callable. Alex, você tem alguma ideia disso? obrigado!
trilhões
1
Código em execução no encadeamento personalizado, pois qualquer outro código pode gerar exceção. Para capturá-lo em outro encadeamento, você deve executar alguns esforços usando o mecanismo de notificação personalizado (por exemplo, com base em ouvintes) ou usando Futureou adicionando gancho que captura todas as exceções não encontradas: docs.oracle.com/javase/6/docs/api/ java / lang /…
AlexR
Ótima informação! Obrigado Alex! :)
trilhões
1
Votei positivamente nesta resposta porque ela afirma (corretamente, se tirada pelo valor nominal) que você deve usar o modelo de pool de threads com objetos que podem ser chamados. A coisa aparentemente lamentável sobre isso é que não se pode estender o Threaduso significativo da Callableinterface para que um único encadeamento possa ser personalizado para fazer coisas que podem ser chamadas e outras que o desenvolvedor possa querer. Se qualquer um que lê este comentário pensa que eu estou errado, eu gostaria de conhecer melhor ...
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|+-------------------------------------+--------------------------------------------------------------------------------------------------+
Os designers de Java sentiram a necessidade de estender os recursos da Runnableinterface, mas não queriam afetar os usos da Runnableinterface e provavelmente essa foi a razão pela qual eles optaram por ter uma interface separada nomeada Callableno Java 1.5 do que alterar o já Runnableinterface existente que faz parte do Java desde o Java 1.0. fonte
É importante enfatizar que a exceção marcada , não a RuntimeException
BertKing,
5
Callable e Runnable são semelhantes entre si e podem ser usados na implementação de threads. No caso de implementar o Runnable, você deve implementar o método run () , mas, no caso de callable, deve implementar o método call () , ambos os métodos funcionam de maneira semelhante, mas callable () método tem mais flexibilidade. Existem algumas diferenças entre eles.
Diferença entre Runnable e Callable como abaixo--
1) O método run () de runnable retorna nulo , significa que se você deseja que seu thread retorne algo que possa ser usado mais, então você não tem escolha com o método runnable run () . Existe uma solução 'Callable' . Se você quiser retornar qualquer coisa na forma de objeto , use Callable em vez de Runnable . Interface callable tem o método 'call ()' que retorna Object .
Assinatura do método - Executável->
publicvoid run(){}
Chamadas->
publicObject call(){}
2) No caso do método runnable run () , se surgir alguma exceção verificada, você deve precisar lidar com o bloco try catch , mas, no caso do método Callable call () , é possível lançar a exceção verificada conforme abaixo
publicObject call()throwsException{}
3) Runnable vem da versão legada do java 1.0 , mas callable veio na versão Java 1.5 com o Executer estrutura .
Se você estiver familiarizado com Executores , use Callable em vez de Runnable .
Executável (vs) Callable entra em quando estamos usando a estrutura do Executer.
ExecutorService é uma subinterface de Executor, que aceita tarefas Runnable e Callable.
O Multi-Threading anterior pode ser alcançado usando a Interface Desde 1.0 , mas aqui o problema ocorre após a conclusão da tarefa de encadeamento, não podemos coletar as informações dos Encadeamentos. Para coletar os dados, podemos usar campos estáticos.Runnable
Exemplo Segmentos separados para coletar os dados de cada aluno.
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());}
Para resolver esse problema, eles introduziram o From 1.5, que retorna um resultado e pode gerar uma exceção.Callable<V>
Método abstrato único : As interfaces Callable e Runnable têm um único método abstrato, o que significa que podem ser usadas em expressões lambda no java 8.
Existem algumas maneiras diferentes de delegar tarefas para execução em um ExecutorService .
execute(Runnable task):void cria novo encadeamento, mas não bloqueia o encadeamento principal ou o chamador, pois esse método retorna nulo.
submit(Callable<?>):Future<?>, submit(Runnable):Future<?>cria novo encadeamento e bloqueia o encadeamento principal quando você estiver usando future.get () .
Exemplo de uso da interface Interfaces executável, configurável com estrutura de executor.
classCallableTaskimplementsCallable<Integer>{privateint num =0;publicCallableTask(int num){this.num = num;}@OverridepublicInteger call()throwsException{String threadName =Thread.currentThread().getName();System.out.println(threadName +" : Started Task...");for(int i =0; i <5; i++){System.out.println(i +" : "+ threadName +" : "+ num);
num = num + i;MainThread_Wait_TillWorkerThreadsComplete.sleep(1);}System.out.println(threadName +" : Completed Task. Final Value : "+ num);return num;}}classRunnableTaskimplementsRunnable{privateint num =0;publicRunnableTask(int num){this.num = num;}@Overridepublicvoid run(){String threadName =Thread.currentThread().getName();System.out.println(threadName +" : Started Task...");for(int i =0; i <5; i++){System.out.println(i +" : "+ threadName +" : "+ num);
num = num + i;MainThread_Wait_TillWorkerThreadsComplete.sleep(1);}System.out.println(threadName +" : Completed Task. Final Value : "+ num);}}publicclassMainThread_Wait_TillWorkerThreadsComplete{publicstaticvoid main(String[] args)throwsInterruptedException,ExecutionException{System.out.println("Main Thread start...");Instant start = java.time.Instant.now();
runnableThreads();
callableThreads();Instant end = java.time.Instant.now();Duration between = java.time.Duration.between(start, end);System.out.format("Time taken : %02d:%02d.%04d \n", between.toMinutes(), between.getSeconds(), between.toMillis());System.out.println("Main Thread completed...");}publicstaticvoid runnableThreads()throwsInterruptedException,ExecutionException{ExecutorService executor =Executors.newFixedThreadPool(4);Future<?> f1 = executor.submit(newRunnableTask(5));Future<?> f2 = executor.submit(newRunnableTask(2));Future<?> f3 = executor.submit(newRunnableTask(1));// Waits until pool-thread complete, return null upon successful completion.System.out.println("F1 : "+ f1.get());System.out.println("F2 : "+ f2.get());System.out.println("F3 : "+ f3.get());
executor.shutdown();}publicstaticvoid callableThreads()throwsInterruptedException,ExecutionException{ExecutorService executor =Executors.newFixedThreadPool(4);Future<Integer> f1 = executor.submit(newCallableTask(5));Future<Integer> f2 = executor.submit(newCallableTask(2));Future<Integer> f3 = executor.submit(newCallableTask(1));// Waits until pool-thread complete, returns the result.System.out.println("F1 : "+ f1.get());System.out.println("F2 : "+ f2.get());System.out.println("F3 : "+ f3.get());
executor.shutdown();}}
Respostas:
Veja a explicação aqui .
fonte
Basicamente sim. Veja as respostas para esta pergunta . E o javadoc para
Callable
.Porque a
Runnable
interface não pode fazer tudo o queCallable
faz!Runnable
existe desde o Java 1.0, masCallable
foi introduzido apenas no Java 1.5 ... para lidar com casos de uso queRunnable
não suportam. Em teoria, a equipe Java poderia ter alterado a assinatura doRunnable.run()
método, mas isso quebraria a compatibilidade binária com o código anterior à 1.5, exigindo recodificação ao migrar o código Java antigo para as JVMs mais recentes. Isso é um GRANDE NÃO-NÃO. O Java se esforça para ser compatível com versões anteriores ... e esse tem sido um dos maiores pontos de venda do Java para computação comercial.E, obviamente, existem casos de uso em que uma tarefa não precisa retornar um resultado ou lançar uma exceção verificada. Para esses casos de uso, usar
Runnable
é mais conciso do que usarCallable<Void>
e retornar umnull
valor dummy ( ) docall()
métodofonte
Runnable
existe (em grande parte) por motivos de compatibilidade com versões anteriores. Mas não há situações em que é desnecessário ou muito caro implementar (ou exigir)Callable
interface (por exemplo, inScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)
)? Portanto, não há um benefício em manter as duas interfaces no idioma, mesmo que a história não force o resultado atual?Runnable
teria sido modificado se não houvesse um imperativo para manter a compatibilidade. O "clichê" dereturn null;
é um argumento fraco. (Pelo menos, essa teria sido a minha decisão ... no contexto hipotético onde você poderia ignorar compatibilidade com versões anteriores.)Callable
precisa implementar ocall()
método enquanto outroRunnable
precisa implementar orun()
método.Callable
pode retornar um valor, masRunnable
não pode.Callable
pode lançar exceção marcada, mas umRunnable
não pode.A
Callable
pode ser usado comExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)
métodos, mas aRunnable
não pode ser.fonte
Encontrei isso em outro blog que pode explicar um pouco mais essas diferenças :
Embora ambas as interfaces sejam implementadas pelas classes que desejam executar em um encadeamento de execução diferente, existem poucas diferenças entre as duas interfaces:
Callable<V>
instância retorna um resultado do tipoV
, enquanto umaRunnable
instância não.Callable<V>
instância pode gerar exceções verificadas, enquanto umaRunnable
instância não podeOs designers de Java sentiram a necessidade de estender os recursos da
Runnable
interface, mas não queriam afetar os usos daRunnable
interface e provavelmente essa foi a razão pela qual eles optaram por ter uma interface separada nomeadaCallable
no Java 1.5 do que alterar o já existenteRunnable
.fonte
Vejamos onde alguém usaria Runnable e Callable.
Runnable e Callable são executados em um thread diferente do thread de chamada. Mas Callable pode retornar um valor e Runnable não. Então, onde isso realmente se aplica.
Runnable : Se você tiver uma tarefa de ignorar e esquecer, use Runnable. Coloque seu código dentro de um Runnable e, quando o método run () for chamado, você poderá executar sua tarefa. O segmento de chamada realmente não se importa quando você executa sua tarefa.
Chamada : Se você estiver tentando recuperar um valor de uma tarefa, use Chamada. Agora que pode ser chamado por si só não fará o trabalho. Você precisará de um futuro que envolva seu Callable e obtenha seus valores em future.get (). Aqui, o encadeamento de chamada será bloqueado até que o futuro volte com resultados que, por sua vez, aguardam a execução do método call () de Callable.
Portanto, pense em uma interface para uma classe de destino em que você tenha os métodos agrupados Runnable e Callable definidos. A classe de chamada aleatoriamente chamará os métodos da interface sem saber qual é Runnable e qual é Callable. Os métodos Runnable serão executados de forma assíncrona, até que um método Callable seja chamado. Aqui, o encadeamento da classe de chamada será bloqueado, pois você está recuperando valores da sua classe de destino.
NOTA: Dentro da classe de destino, você pode fazer chamadas para Callable e Runnable em um único executor de encadeamento, tornando esse mecanismo semelhante a uma fila de despacho serial. Desde que o chamador chame seus métodos agrupados Runnable, o thread de chamada será executado muito rápido, sem bloquear. Assim que chamar um método Callable envolvido no futuro, ele deverá ser bloqueado até que todos os outros itens na fila sejam executados. Somente então o método retornará com valores. Este é um mecanismo de sincronização.
fonte
Callable
interface declaracall()
método e você precisa fornecer genéricos, pois o tipo de chamada de objeto () deve retornar -Runnable
por outro lado, é a interface que declara orun()
método chamado quando você cria um Thread com o executável e chama start (). Você também pode chamar diretamente run (), mas que apenas executa o método run () é o mesmo encadeamento.Para resumir algumas diferenças notáveis são
Runnable
objeto não retorna um resultado, enquanto umCallable
objeto retorna um resultado.Runnable
objeto não pode lançar uma exceção marcada, enquanto umCallable
objeto pode lançar uma exceção.Runnable
interface existe desde o Java 1.0, enquantoCallable
foi introduzida apenas no Java 1.5.Poucas semelhanças incluem
Os métodos na interface ExecutorService são
fonte
Objetivo dessas interfaces da documentação da Oracle:
A interface executável deve ser implementada por qualquer classe cujas instâncias sejam executadas por a
Thread
. A classe deve definir um método sem argumentos chamadosrun
.Callable : uma tarefa que retorna um resultado e pode gerar uma exceção. Os implementadores definem um único método sem argumentos chamados de chamada. A
Callable
interface é semelhanteRunnable
, pois ambas são projetadas para classes cujas instâncias são potencialmente executadas por outro encadeamento. UMARunnable
, no entanto, não retorna um resultado e não pode gerar uma exceção verificada.Outras diferenças:
Você pode passar
Runnable
para criar um Thread . Mas você não pode criar um novo thread passandoCallable
como parâmetro. Você pode passar Callable apenas paraExecutorService
instâncias.Exemplo:
Use
Runnable
para fogo e esqueça as chamadas. UseCallable
para verificar o resultado.Callable
pode ser passado para invokeAll método diferenteRunnable
. MétodosinvokeAny
einvokeAll
execute as formas mais úteis de execução em massa, executando uma coleção de tarefas e aguardando pelo menos uma, ou todas, para concluirDiferença trivial: nome do método a ser implementado =>
run()
paraRunnable
ecall()
paraCallable
.fonte
Como já foi mencionado aqui, Callable é uma interface relativamente nova e foi introduzida como parte do pacote de simultaneidade. Callable e Runnable podem ser usados com executores. O thread de classe (que implementa o próprio Runnable) oferece suporte apenas ao Runnable.
Você ainda pode usar o Runnable com executores. A vantagem do Callable é que você pode enviá-lo ao executor e retornar imediatamente o resultado futuro que será atualizado quando a execução for concluída. O mesmo pode ser implementado com o Runnable, mas nesse caso você precisa gerenciar os resultados sozinho. Por exemplo, você pode criar uma fila de resultados que conterá todos os resultados. Outro encadeamento pode esperar nessa fila e lidar com os resultados que chegarem.
fonte
Future
ou adicionando gancho que captura todas as exceções não encontradas: docs.oracle.com/javase/6/docs/api/ java / lang /…Thread
uso significativo daCallable
interface para que um único encadeamento possa ser personalizado para fazer coisas que podem ser chamadas e outras que o desenvolvedor possa querer. Se qualquer um que lê este comentário pensa que eu estou errado, eu gostaria de conhecer melhor ...Os designers de Java sentiram a necessidade de estender os recursos da
Runnable
interface, mas não queriam afetar os usos daRunnable
interface e provavelmente essa foi a razão pela qual eles optaram por ter uma interface separada nomeadaCallable
no Java 1.5 do que alterar o jáRunnable
interface existente que faz parte do Java desde o Java 1.0. fontefonte
As diferenças entre Callable e Runnable são as seguintes:
fonte
Callable e Runnable são semelhantes entre si e podem ser usados na implementação de threads. No caso de implementar o Runnable, você deve implementar o método run () , mas, no caso de callable, deve implementar o método call () , ambos os métodos funcionam de maneira semelhante, mas callable () método tem mais flexibilidade. Existem algumas diferenças entre eles.
Diferença entre Runnable e Callable como abaixo--
1) O método run () de runnable retorna nulo , significa que se você deseja que seu thread retorne algo que possa ser usado mais, então você não tem escolha com o método runnable run () . Existe uma solução 'Callable' . Se você quiser retornar qualquer coisa na forma de objeto , use Callable em vez de Runnable . Interface callable tem o método 'call ()' que retorna Object .
Assinatura do método - Executável->
Chamadas->
2) No caso do método runnable run () , se surgir alguma exceção verificada, você deve precisar lidar com o bloco try catch , mas, no caso do método Callable call () , é possível lançar a exceção verificada conforme abaixo
3) Runnable vem da versão legada do java 1.0 , mas callable veio na versão Java 1.5 com o Executer estrutura .
Se você estiver familiarizado com Executores , use Callable em vez de Runnable .
Espero que você entenda.
fonte
Executável (vs) Callable entra em quando estamos usando a estrutura do Executer.
ExecutorService é uma subinterface de
Executor
, que aceita tarefas Runnable e Callable.O Multi-Threading anterior pode ser alcançado usando a Interface Desde 1.0 , mas aqui o problema ocorre após a conclusão da tarefa de encadeamento, não podemos coletar as informações dos Encadeamentos. Para coletar os dados, podemos usar campos estáticos.
Runnable
Exemplo Segmentos separados para coletar os dados de cada aluno.
Para resolver esse problema, eles introduziram o From 1.5, que retorna um resultado e pode gerar uma exceção.
Callable<V>
Método abstrato único : As interfaces Callable e Runnable têm um único método abstrato, o que significa que podem ser usadas em expressões lambda no java 8.
Existem algumas maneiras diferentes de delegar tarefas para execução em um ExecutorService .
execute(Runnable task):void
cria novo encadeamento, mas não bloqueia o encadeamento principal ou o chamador, pois esse método retorna nulo.submit(Callable<?>):Future<?>
,submit(Runnable):Future<?>
cria novo encadeamento e bloqueia o encadeamento principal quando você estiver usando future.get () .Exemplo de uso da interface Interfaces executável, configurável com estrutura de executor.
fonte
É um tipo de convenção de nomenclatura de interface que combina com a programação funcional
fonte