Em alguns cenários, devemos aguardar a conclusão da execução do thread antes de prosseguir para a próxima etapa. Por exemplo, alguns programas precisam inicializar alguns recursos antes de iniciar a execução. Neste momento, podemos iniciar um thread especificamente para realizar a tarefa de inicialização e esperar até que a tarefa do thread seja concluída antes de executar outras partes.
Para isso, a classe Thread nos fornece o método join(). Quando chamamos esse método usando um objeto thread, o objeto thread chamador será atrasado até que o objeto chamado conclua a execução antes de iniciar a execução.
Nesta seção, o programa de amostra demonstra a espera pela conclusão do método de inicialização antes de executar outras tarefas.
saiba disso
Siga as etapas mostradas abaixo para concluir o programa de amostra.
1. Crie uma classe chamada DataSourcesLoader e implemente a interface Runnable. O código é o seguinte:
Copie o código do código da seguinte forma:
A classe pública DataSourcesLoader implementa Runnable {
2. Implemente o método run(), imprima uma mensagem no console para indicar o início da execução, depois durma por 4 segundos e imprima uma mensagem no console para indicar o fim da execução do thread. O código é o seguinte:
Copie o código do código da seguinte forma:
@Substituir
execução void pública() {
System.out.printf("Início do carregamento das fontes de dados: %s/n",
nova Data());
tentar {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("O carregamento das fontes de dados foi concluído: %s/n",
nova Data());
}
3. Crie uma classe chamada NetworkConnectionsLoader e implemente a interface Runnable. Implemente o método run(). O código deste método é igual ao método run() da classe DataSourcesLoader, exceto que ele dorme por 6 segundos.
4. Implemente a classe principal do exemplo e implemente o método main(). O código é o seguinte:
Copie o código do código da seguinte forma:
classe pública Principal {
public static void main(String[] args) {
5. Crie um objeto DataSourcesLoader e um objeto Thread para iniciar sua execução. O código é o seguinte:
Copie o código do código da seguinte forma:
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourcesLoader");
6. Crie um objeto NetworkConnectionsLoader e um objeto Thread para iniciar sua execução. O código é o seguinte:
Copie o código do código da seguinte forma:
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionsLoader");
7. Chame o método start() dos dois objetos Thread. O código é o seguinte:
Copie o código do código da seguinte forma:
thread1.start();
thread2.start();
8. Chame o método join() para aguardar que os dois threads concluam suas tarefas. Este método lançará InterruptedException, então capture esta exceção. O código é o seguinte:
Copie o código do código da seguinte forma:
tentar {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
9. Imprima uma frase no console para indicar o fim da execução do programa. O código é o seguinte:
Copie o código do código da seguinte forma:
System.out.printf("Principal: Configuração foi carregada: %s/n",
nova Data());
10. Execute o programa e verifique o efeito da execução.
sabe por que
Ao executar este programa de exemplo, podemos ver duas threads iniciando sua execução. Primeiro, o DataSourcesLoader conclui sua execução; em seguida, o NetworkConnectionsLoader conclui sua execução; Neste ponto, o thread principal continua sua execução e então imprime uma mensagem de encerramento no console.
sem fim
Java fornece dois outros métodos join() sobrecarregados:
Copie o código do código da seguinte forma:
join(longos milissegundos)
join(milissegundos longos, nanos longos)
O primeiro método não espera até que seja chamado para concluir a tarefa, mas aguarda o tempo especificado pelo parâmetro antes de iniciar a execução, por exemplo, se thread1 chamar esse método, thread1.join(1000), quando o thread thread1 encontrar um dos threads; as seguintes condições continuarão a ser executadas:
1.thread2 completa sua execução;
2.Após 1000 milissegundos;
Quando uma dessas duas condições for verdadeira, o método join() retornará e continuará executando a tarefa original.
O segundo método é muito semelhante ao primeiro método, exceto que possui um parâmetro de tempo adicional de nanossegundos.
Usar doutrina
Este artigo foi traduzido do "Java 7 Concurrency Cookbook" (D Gua Ge o roubou como "Java7 Concurrency Sample Collection") e é usado apenas como material de aprendizagem. Não pode ser utilizado para quaisquer fins comerciais sem autorização.
Pequeno sucesso
A versão completa do código de exemplo usado nesta seção.
O código completo da classe DataSourcesLoader é o seguinte:
pacote com.diguage.books.concurrencycookbook.chapter1.recipe6;
importar java.util.Date;
importar java.util.concurrent.TimeUnit;
/**
* Data: 19/09/2013
* Horário: 09h15
*/
A classe pública DataSourcesLoader implementa Runnable {
@Substituir
execução void pública() {
System.out.printf("Início do carregamento das fontes de dados: %s/n",
nova Data());
tentar {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("O carregamento das fontes de dados foi concluído: %s/n",
nova Data());
}
}
Código completo da classe NetworkConnectionsLoader
Copie o código do código da seguinte forma:
pacote com.diguage.books.concurrencycookbook.chapter1.recipe6;
importar java.util.Date;
importar java.util.concurrent.TimeUnit;
/**
* Data: 19/09/2013
* Horário: 09h21
*/
A classe pública NetworkConnectionsLoader implementa Runnable {
@Substituir
execução void pública() {
System.out.printf("Início do carregamento das fontes de dados: %s/n",
nova Data());
tentar {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("O carregamento das fontes de dados foi concluído: %s/n",
nova Data());
}
}
O código completo da classe principal
Copie o código do código da seguinte forma:
pacote com.diguage.books.concurrencycookbook.chapter1.recipe6;
importar java.util.Date;
/**
* Data: 19/09/2013
* Horário: 09h25
*/
classe pública Principal {
public static void main(String[] args) {
DataSourcesLoader dsLoader = new DataSourcesLoader();
Thread thread1 = new Thread(dsLoader, "DataSourcesLoader");
NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
Thread thread2 = new Thread(ncLoader, "NetworkConnectionsLoader");
thread1.start();
thread2.start();
tentar {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Principal: Configuração foi carregada: %s/n",
nova Data());
}
}