Compartilhamento de tecnologia

O thread principal termina e o thread filho não é mais executado

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Contexto do problema:

O motivo é que ao fazer bloqueios distribuídos, criei 10 threads no teste de unidade e depois os iniciei. Cada thread imprimirá conteúdo no método run, mas os resultados do teste na verdade não produzirão nada. Fiquei muito confuso e então especulei que o thread principal poderia ter terminado a execução do subthread e terminado diretamente, adicionar thread.join() obteve o resultado esperado.

Conclusão do problema:

Este problema não existe se estiver escrito no método principal, mas existe em testes únicos.

Processo problemático:

Código original:

  1. @Test
  2. public void multipleThreadTest(){
  3. System.out.println(Thread.currentThread().getName());
  4. LockThread[] lockThreads = new LockThread[10];
  5. for (int i=0;i< lockThreads.length;i++){
  6. lockThreads[i] = new LockThread(new ZkNodeNoneBlockingLock("app"));
  7. }
  8. for (LockThread lockThread : lockThreads) {
  9. lockThread.start();
  10. }
  11. }
  12. private static class LockThread extends Thread{
  13. ZkNodeNoneBlockingLock locker;
  14. public LockThread(ZkNodeNoneBlockingLock locker){
  15. this.locker = locker;
  16. }
  17. @Override
  18. public void run() {
  19. boolean lock = locker.lock();
  20. System.out.println(this.getName() + (lock ? "上锁成功" : "上锁失败"));
  21. }
  22. }

Código modificado:

  1. @Test
  2. public void multipleThreadTest(){
  3. System.out.println(Thread.currentThread().getName());
  4. LockThread[] lockThreads = new LockThread[10];
  5. for (int i=0;i< lockThreads.length;i++){
  6. lockThreads[i] = new LockThread(new ZkNodeNoneBlockingLock("app"));
  7. }
  8. for (LockThread lockThread : lockThreads) {
  9. lockThread.start();
  10. }
  11. for (LockThread lockThread : lockThreads){
  12. try {
  13. lockThread.join();
  14. } catch (InterruptedException e) {
  15. throw new RuntimeException(e);
  16. }
  17. }
  18. }
  19. private static class LockThread extends Thread{
  20. ZkNodeNoneBlockingLock locker;
  21. public LockThread(ZkNodeNoneBlockingLock locker){
  22. this.locker = locker;
  23. }
  24. @Override
  25. public void run() {
  26. boolean lock = locker.lock();
  27. System.out.println(this.getName() + (lock ? "上锁成功" : "上锁失败"));
  28. }
  29. }

Observação:

Thread.join() é o thread atual, ou seja, o thread principal não pode continuar a ser executado até que a execução do thread seja concluída.