Pode ser traduzido como uma trava de contagem regressiva (contagem regressiva). Escusado será dizer que a trava significa, como o nome indica, para evitar o progresso. Aqui isso significa que o método CountdownLatch.await () bloqueará o encadeamento atual antes que a contagem regressiva seja 0.
O CountdownLatch é uma classe auxiliar síncrona que permite que um ou mais threads esperem até que um conjunto de operações seja executado em outros threads.
O CountDownLatch funciona semelhante ao método Thread.join () e pode ser usado para a colaboração entre um grupo de threads e outro grupo de threads. Por exemplo, o encadeamento principal precisa de uma série de preparativos antes de fazer um trabalho e somente se todos esses preparativos forem concluídos, o encadeamento principal continuará seu trabalho. Esses preparativos são independentes um do outro, para que possam ser executados simultaneamente para aumentar a velocidade. Nesse cenário, o CountdownLatch pode ser usado para coordenar o agendamento entre os threads. Na época em que os threads foram criados diretamente (antes do Java 5.0), podemos usar thread.join (). Depois que o JUC aparece, como os threads no pool de threads não podem ser referenciados diretamente, o CountdownLatch deve ser usado.
A classe Countdownlatch é um contador síncrono. Ao construir, o parâmetro int é passado. Este parâmetro é o valor inicial do contador. Toda vez que o método Countdown () é chamado, o contador é diminuído em 1 e o contador é maior que 0, o método aguardar () bloqueará o programa e continuará a execução. O CountdownLatch pode ser considerado como uma trava de contagem regressiva, desencadeando um evento específico quando a contagem é reduzida para 0. Usando esse recurso, o thread principal pode aguardar o final do encadeamento filho. A seguir, é apresentado um exemplo de uma competição simulada de atleta.
Um cenário de aplicação muito típico do CountdownLatch é: há uma tarefa que deseja ser executada para baixo, mas você deve esperar até que outras tarefas sejam executadas antes que você possa continuar sendo executado para baixo. Se nossa tarefa que desejarmos continuar executando ainda mais chamadas o método Await () do objeto Countdownlatch, e as outras tarefas chamam o método Countdown () no mesmo objeto Countdownlatch após executar suas próprias tarefas, a tarefa que chama o método Await () continuará bloqueando e aguardando até que o valor da contagem da contagem regressiva diminua para 0.
Lista de funções Countdownlatch
O CountDownLatch (int conting) constrói um CountdownLatch inicializado com uma determinada contagem. // Faça o thread atual aguarde até que a trava conte zero, a menos que o thread seja interrompido. Void Await () // faz com que o thread atual aguarde até que a trava conte zero, a menos que o thread seja interrompido ou o tempo de espera especificado seja excedido. Boolean Aguarda (tempo limite de longo prazo, unidade de unidade de tempo) // decrem a contagem da trava. Se a contagem atingir zero, todos os threads de espera serão lançados. Void Countdown () // Retorna a contagem atual. long getCount () // retorna uma string que identifica esta trava e seu status. String ToString ()
Estrutura de dados CountdownLatch
O diagrama de classe UML de Countdownlatch é o seguinte:
A estrutura de dados da Countdownlatch é simples, é implementada por meio de "bloqueios compartilhados". Ele contém objetos de sincronização, sincronização é o tipo de sincronização. Sync é uma classe de instância, que herda do AQS.
Exemplo de Countdownlatch
O seguinte é implementado através do CountdownLatch: "Principal Thread" aguarda "5 threads de crianças" para concluir o "trabalho especificado (1000ms)" antes de continuar a ser executado.
importar java.util.concurrent.countdownlatch; importar java.util.concurrent.cyclicBarrier; public class Class CountdownLatchTest1 {private static int latch_size = 5; Countdownlatch private estático Donesignal; public static void main (string [] args) {try {Donesignal = new CountdownLatch (latch_size); // Crie 5 novas tarefas para (int i = 0; i <latch_size; i ++) new InnerThread (). Start (); System.out.println ("Main Aguardar Begin"); // "Thread Main" aguarda a conclusão de 5 tarefas no pool de threads para concluir o Donesignal.await (); System.out.println ("Main Aguardait terminado"); } catch (interruptedException e) {e.printStackTrace (); }} classe estática interno estende o thread {public void run () {try {thread.sleep (1000); System.out.println (thread.currentThread (). GetName () + "sono 1000ms."); // subtraia o valor de Countdownlatch por 1 Donesignal.CountDown (); } catch (interruptedException e) {e.printStackTrace (); }}}} Resultados em execução:
Principal Aguarda Begin.Thread-0 Sleep 1000ms.thread-2 Sleep 1000ms.thread-1 Sleep 1000ms.Thread-4 Sleep 1000ms.Thread-3 Sleep 1000ms.Main Aguardine.
A descrição do resultado: o encadeamento principal usa donesignal.await () para aguardar outros threads para diminuir o Donesignal para 0. Os outros 5 threads inerthread, cada um deles subtraia o valor do Donesignal por 1 através do Donesignal.CountDown (); Quando o Donesignal é 0, Main continuará sendo executado após ser despertado.
PS: Diferença entre Countdownlatch e CyclicBarrier:
(1) A função do CountDownLatch é permitir que 1 ou N threads aguardem que outros threads concluam a execução; Enquanto o CyclicBarrier permite que N threads esperem um pelo outro.
(2) o balcão de contagem regressivo não pode ser redefinido; O balcão de CyclicBarrier pode ser usado após a redefinição, por isso é chamado de barreira em loop.