Qual é a maneira de simplesmente esperar que todo o processo encadeado termine? Por exemplo, digamos que eu tenho:
public class DoSomethingInAThread implements Runnable{
public static void main(String[] args) {
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread());
t.start();
}
// wait for all threads' run() methods to complete before continuing
}
public void run() {
// do something here
}
}
Como altero isso para que o main()
método pause no comentário até que todos os run()
métodos de encadeamento sejam encerrados? Obrigado!
java
multithreading
parallel-processing
wait
DivideByHero
fonte
fonte
Uma maneira seria criar um
List
deThread
s, criar e lançar cada tópico, enquanto o adicionava à lista. Depois que tudo for iniciado, volte para a lista e chamejoin()
cada um. Não importa em que ordem os threads terminam de ser executados, tudo o que você precisa saber é que, no momento em que o segundo loop termina, cada thread terá sido concluída.Uma abordagem melhor é usar um ExecutorService e seus métodos associados:
Usar um ExecutorService (e todas as coisas novas dos utilitários de simultaneidade do Java 5 ) é incrivelmente flexível, e o exemplo acima mal arranha a superfície.
fonte
fonte
em vez de
join()
, que é uma API antiga, você pode usar CountDownLatch . Modifiquei seu código conforme abaixo para atender às suas necessidades.Explicação :
CountDownLatch
foi inicializado com a contagem fornecida 1000 de acordo com sua exigência.Cada thread de trabalho
DoSomethingInAThread
diminuirá oCountDownLatch
, que foi passado no construtor.Tópico principal
CountDownLatchDemo
await()
até a contagem chegar a zero. Quando a contagem chegar a zero, você ficará abaixo da linha na saída.Mais informações na página de documentação do oracle
Consulte a pergunta SE relacionada para outras opções:
espere até que todos os threads terminem seu trabalho em java
fonte
Evite a classe Thread e, em vez disso, use as abstrações superiores fornecidas em java.util.concurrent
A classe ExecutorService fornece o método invokeAll que parece fazer exatamente o que você deseja.
fonte
Considere usar
java.util.concurrent.CountDownLatch
. Exemplos em javadocsfonte
Como sugeriu Martin K
java.util.concurrent.CountDownLatch
parece ser a melhor solução para isso. Apenas adicionando um exemplo para o mesmofonte
Dependendo de suas necessidades, você também pode verificar as classes CountDownLatch e CyclicBarrier no pacote java.util.concurrent. Eles podem ser úteis se você quiser que seus threads esperem uns pelos outros, ou se quiser um controle mais refinado sobre a maneira como seus threads são executados (por exemplo, aguardando em sua execução interna por outro thread para definir algum estado). Você também pode usar um CountDownLatch para sinalizar todos os seus threads para iniciar ao mesmo tempo, em vez de iniciá-los um por um conforme você itera em seu loop. Os documentos padrão da API têm um exemplo disso, além de usar outro CountDownLatch para esperar que todos os threads concluam sua execução.
fonte
Se você fizer uma lista de threads, poderá percorrê-los e .join () em cada um deles, e seu loop terminará quando todos os threads tiverem terminado. Eu ainda não tentei.
http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join ()
fonte
Crie o objeto thread dentro do primeiro loop for.
E então o que todos aqui estão dizendo.
fonte
Você pode fazer isso com o objeto "ThreadGroup" e seu parâmetro activeCount :
fonte
Como alternativa ao CountDownLatch, você também pode usar CyclicBarrier, por exemplo
Para usar CyclicBarrier, neste caso, o tipo de barreira.await () deve ser a última instrução, ou seja, quando sua thread terminar seu trabalho. CyclicBarrier pode ser usado novamente com seu método reset (). Para citar javadocs:
Um CyclicBarrier oferece suporte a um comando Runnable opcional que é executado uma vez por ponto de barreira, após a chegada do último encadeamento no grupo, mas antes de qualquer encadeamento ser liberado. Esta ação de barreira é útil para atualizar o estado compartilhado antes que qualquer uma das partes continue.
fonte
Não
join()
foi útil para mim. veja este exemplo em Kotlin:O resultado:
Agora, deixe-me usar o
join()
para tópicos:E o resultado:
Como fica claro quando usamos
join
:Nossa solução para evitar o bloqueio de outros threads foi criar um ArrayList:
Agora, quando queremos iniciar um novo thread, devemos adicioná-lo ao ArrayList:
A
addThreadToArray
função:A
startNewThread
função:Verifique a conclusão dos threads conforme abaixo em todos os lugares necessários:
fonte