기술나눔

메인 스레드가 종료되고 하위 스레드가 더 이상 실행되지 않습니다.

2024-07-12

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

문제 배경:

그 이유는 분산 잠금을 할 때 단위 테스트에서 스레드를 10개 생성한 후 시작했기 때문입니다. 각 스레드는 run 메서드의 내용을 인쇄하지만 테스트 결과는 실제로 아무것도 출력하지 않습니다. 나는 매우 당황했고, 메인 스레드가 하위 스레드 실행을 마치고 바로 종료되었을 수도 있다고 추측했습니다. 물론, thread.join()을 추가하면 예상한 결과를 얻었습니다.

문제 결론:

메인 메소드에서는 이런 문제가 발생하지 않지만, 싱글 테스트에서는 이런 문제가 발생합니다.

문제 프로세스:

원본 코드:

  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. }

수정된 코드:

  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. }

메모:

Thread.join()은 현재 스레드입니다. 즉, 스레드 스레드의 실행이 완료될 때까지 기본 스레드는 계속 실행할 수 없습니다.