[개발 일기] 2025.03.03 - Thread 조정 (동기화)

2025. 3. 3. 13:52·개발 일기

💡 개요

오늘은 자바 멀티스레딩의 Thread 동기화 기법에서 사용되는 join() 에 대해 정리해 보자.

 

 

 

📕 Thread 동기화

스레드 조정에는 스레드 종료와 스레드 동기화가 사용된다.

 

 

스레드 동기화란 여러 스레드가 공유 자원에 동시에 접근할 때 발생하는 문제(경쟁 조건, 데이터 불일치 등)를 방지하기 위한 기법이다.

 

 

스레드 동기화엔 많은 기술이 존재한다. (synchronized, ReentrantLock, volatile, wait(), notify() 등)

 

 

오늘 정리할 동기화 기술은 join()이다.

 

 

 

🛠️ Thread.join()

 

Thread.join() 메서드는 현재 실행 중인 스레드가 특정 다른 스레드의 종료를 기다리도록 하는 메서드이다.

 

 

말만 들으면 이해하기 어려우니, 다음 예시를 보자.

 

 

작업을 수행중인 스레드A와 스레드B가 있다.

 

 

만약 스레드B의 작업이 스레드A 작업의 결괏값을 필요로 하는 작업이라면, 반드시 스레드A가 정상적으로 완료된 후, 스레드B가 실행되어야 한다. 

 

 

 

만약 스레드 동기화를 하지 않으면, 스레드B는 계속해서 스레드A의 작업의 완료되었는지 확인하는 작업을 해야 한다.

 

 

이러한 작업을 반복한다면 CPU 사이클을 계속해서 태우기 때문에 스레드A를 느리게 만들 수 있다.

 

 

이럴 바엔 차라리 스레드B를 스레드A의 작업이 완료되기 전까지 재워버리는 것도 하나의 방법이긴 할 듯..

 

 

public class Main {

    static int threadAResult;
    static int threadBResult;

    public static void main(String[] args) {
        Thread threadA = new Thread(new ThreadA(10));
        Thread threadB = new Thread(new ThreadB());

        threadA.start();
        threadB.start();

        System.out.println(threadBResult);
    }

    static class ThreadA implements Runnable {

        private int num;

        public ThreadA(int num) {
            this.num = num;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(100000);
                threadAResult = this.num;
            } catch (InterruptedException e) {
                System.out.println("interrupt 발생");
            }
        }
    }

    static class ThreadB implements Runnable {
        @Override
        public void run() {
            for (int i = 0 ; i < 10 ; i++) {
                threadBResult += threadAResult;
            }
        }
    }
}

 

 

위의 코드는 위에 작성한 상황을 대략적으로 구현한 것이다.

 

 

과연 이 코드를 실행하면 어떤 결과가 나올까? 바로 0 이다.

 

 

보다시피 threadAResult에 num을 넣기 위해선 100,000ms(100초)을 대기해야 한다.

 

 

하지만 스레드 동기화를 하지 않으면 스레드B는 이것도 모른채 결과값이 완성되기 전인 threadAResult을 사용해 threadBResult의 값을 계산할 것이다.

 

 

이러한 상황을 방지하기 위해선 스레드B는 스레드A의 작업이 종료될 때까지 기다려야 한다.

 

 

이럴 때 사용하는 것이 join() 메서드이다.

 

 

 

 

대략적인 로직은 위의 이미지와 같다.

 

 

public class Main {

    static int threadAResult = 0;
    static int threadBResult = 0;

    public static void main(String[] args) throws InterruptedException {
        Thread threadA = new Thread(new ThreadA(10));
        Thread threadB = new Thread(new ThreadB());

        threadA.start();
        threadA.join(); // threadA가 완료될 때까지 대기
        threadB.start();
        threadB.join(); // threadB가 완료될 때까지 대기
        System.out.println(threadBResult);
    }

		...
		
}

 

 

위의 코드를 실행하면 100이라는 결괏값이 잘 출력된다.

'개발 일기' 카테고리의 다른 글

[개발 일기] 2025.03.05 - 디스크, 파티션, 볼륨 (Docker)  (0) 2025.03.05
[개발 일기] 2025.03.04 - RequestDto에 Getter가 없으면 예외?  (0) 2025.03.04
[개발 일기] 2025.03.02 - Thread 조정 (종료)  (1) 2025.03.02
[개발 일기] 2025.03.01 - Redis 직렬화  (1) 2025.03.01
[개발 일기] 2025.02.28 - @Profiles, @ActiveProfiles  (1) 2025.02.28
'개발 일기' 카테고리의 다른 글
  • [개발 일기] 2025.03.05 - 디스크, 파티션, 볼륨 (Docker)
  • [개발 일기] 2025.03.04 - RequestDto에 Getter가 없으면 예외?
  • [개발 일기] 2025.03.02 - Thread 조정 (종료)
  • [개발 일기] 2025.03.01 - Redis 직렬화
오도형석
오도형석
  • 오도형석
    형석이의 성장일기
    오도형석
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • MSA 모니터링 서비스
        • DB
      • 스파르타 코딩클럽
        • SQL
        • Spring
      • 백엔드
        • Internet
        • Java
        • DB
      • 캡스톤
        • Django
        • 자연어처리
      • Spring
        • JPA
        • MSA
      • ETC
        • ERROR
      • 개발 일기 N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 인기 글

  • 태그

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
오도형석
[개발 일기] 2025.03.03 - Thread 조정 (동기화)
상단으로

티스토리툴바