2017년 4월 12일 수요일

[java][thread] join을 이용하여 thread가 끝났는지 확인하기

join()을 이용하여 thread가 끝났는지 확인하자.

오늘 이런 형태의 소스를 보았다. (아래 내용은 예시)
RunnableClass01 rc01 = new RunnableClass01();
RunnableClass02 rc02 = new RunnableClass02();
RunnableClass03 rc03 = new RunnableClass03();

Thread th01 = new Thread(rc01);
Thread th02 = new Thread(rc02);
Thread th03 = new Thread(rc03);

th01.start();
th02.start();
th03.start();

DB.updateThreadEndsTime(); // 이것이 문제
대충 이런식이었는데... 쓰레드는 끝나지도 않았지만 시작하자마자 스레드가 끝났다는 로직을 실행시킨다.
전체 소스를 보지 않은 나의 탓이 크지만
쓰레드가 완료되었다는 시간을 처리하는 로직은 '당연히' 쓰레드가 전부 끝났을 때 업데이트 할 것이라는 가정이 있었기에 로직 수정 후 낭패를 보았다.
그 후 나는 동료에게 물었다.
"왜 이렇게 해야 하죠? 쓰레드가 끝나고 완료 업데이트를 하면 안되나요?"
"쓰레드는 원래 그래요. 서로 독립적으로 실행되기 때문이죠."
나는 단순하게 join()을 사용해서 그것이 가능함을 보이려 했다.
RunnableClass01 rc01 = new RunnableClass01();
RunnableClass02 rc02 = new RunnableClass01();
RunnableClass03 rc03 = new RunnableClass01();

Thread th01 = new Thread(rc01);
Thread th02 = new Thread(rc02);
Thread th03 = new Thread(rc03);

th01.start();
th02.start();
th03.start();

try {
  th01.join();
  th02.join();
  th03.join();
}catch (Exception e) { }

DB.updateThreadEndsTime(); // 이제 스레드 전부 완료되면 된다.
"이러면 쓰레드 하나가 끝나면 다른 하나가 시작되는 것 아녜요?"
나는 말했다.
"아닙니다. 시작은 같이 하고 끝나는 것만 동기되는 거예요.
어짜피 다 끝나야 완료처리 되야 하는 거니까 다 끝나야 일을 하는것이 맞다고 생각해요." 이렇게 끝났다. 하지만 여기서 하나 더 수정을 해야겠다.
Thread th01 = new Thread(new RunnableClass01());
Thread th02 = new Thread(new RunnableClass02());
Thread th03 = new Thread(new RunnableClass03());

th01.start();
th02.start();
th03.start();

try {
  th01.join();
  th02.join();
  th03.join();
} catch (Exception e) { }

DB.updateThreadEndsTime(); // 이제 스레드 전부 완료되면 된다.
물론 다른 방법도 많겠지만, 실력의 부족과 상황이 여의치 않아 이렇게 단순하게 바꾸는 것 만으로도
로직의 큰 변화가 왔다.
join(), wait(), notify() 같은 것은 기본적으로 알아야할 기능 같다.

댓글 없음:

댓글 쓰기