Обмен технологиями

Основной поток завершается, и дочерний поток больше не выполняется.

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() — это текущий поток, то есть основной поток не может продолжать выполнение до тех пор, пока не завершится выполнение потока потока.