Como devo escolher entre o envio ou execução do ExecutorService , se o valor retornado não for da minha conta?
Se eu testar os dois, não vi diferenças entre os dois, exceto o valor retornado.
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.execute(new Task());
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.submit(new Task());
fonte
Runnable
envolvimentoTask
ou não, que você pode não ter controle. Por exemplo, se vocêExecutor
é realmente umScheduledExecutorService
, sua tarefa será envolvida internamente em umFuture
eThrowable
s não capturados serão vinculados a esse objeto.Future
ou não", é claro. Consulte o Javadoc para ScheduledThreadPoolExecutor # execute , por exemplo.execute : use-o para disparar e esquecer chamadas
submit : use-o para inspecionar o resultado da chamada do método e tomar as ações apropriadas contra as
Future
objeções retornadas pela chamadaDe javadocs
submit(Callable<T> task)
Future<?> submit(Runnable task)
Você deve tomar precauções ao usar
submit()
. Ele oculta exceção na própria estrutura, a menos que você incorpore seu código de tarefa emtry{} catch{}
bloco.Código de exemplo: esse código é engolido
Arithmetic exception : / by zero
.resultado:
O mesmo código é lançado substituindo
submit()
porexecute
():Substituir
com
resultado:
Como lidar com esse tipo de cenário ao usar submit ()?
CustomThreadPoolExecutor
Nova solução:
resultado:
fonte
Se você não se importa com o tipo de retorno, use execute. é o mesmo que enviar, apenas sem o retorno do futuro.
fonte
Retirado do Javadoc:
Pessoalmente, prefiro o uso de execute porque parece mais declarativo, embora isso realmente seja uma questão de preferência pessoal.
Para fornecer mais informações: no caso da
ExecutorService
implementação, a implementação principal retornada pela chamada paraExecutors.newSingleThreadedExecutor()
é umThreadPoolExecutor
.As
submit
chamadas são fornecidas pelo paiAbstractExecutorService
e todas as chamadas são executadas internamente. execute é substituído / fornecido peloThreadPoolExecutor
diretamente.fonte
Do Javadoc :
Portanto, dependendo da implementação,
Executor
você pode descobrir que o encadeamento de envio bloqueia enquanto a tarefa está em execução.fonte
A resposta completa é uma composição de duas respostas que foram publicadas aqui (mais um pouco "extra"):
execute
(porque seu ID de tipo de retornovoid
)execute
espera que umRunnable
temposubmit
possa levar aRunnable
ou aCallable
como argumento (para obter mais informações sobre a diferença entre os dois - veja abaixo).execute
elimina imediatamente quaisquer exceções não verificadas (não pode lançar exceções verificadas !!!), enquantosubmit
vincula qualquer tipo de exceção ao futuro que retornar como resultado e somente quando você chamafuture.get()
uma exceção (empacotada) será lançada. O Throwable que você receberá é uma instânciaExecutionException
e, se você chamar esse objeto,getCause()
ele retornará o Throwable original.Mais alguns pontos (relacionados):
submit
não exija retorno de um resultado, você ainda pode usarCallable<Void>
(em vez de usar umRunnable
).Para resumir, é uma prática melhor usar
submit
com aCallable
(vs.execute
com aRunnable
). E citarei "concorrência simultânea de Java na prática", por Brian Goetz:fonte
Apenas adicionando à resposta aceita-
Fonte
fonte