본문 바로가기
강의 자료/고성능을 강조한 Java 멀티스레딩, 병행성 및 병렬 실행 프로그래밍

섹션 3 : 스레딩 기초 (스레드 연결)

by 토니당 2025. 5. 18.
반응형

💡 Java Thread Coordination (스레드 조정) - Thread.join()


🔍 1️⃣ 개요

  • 멀티스레드 환경에서 스레드가 다른 스레드의 실행 결과가 필요할 어떻게 기다릴지에 대한 문제를 해결합니다.
  • 예를 들어, 스레드 A스레드 B결과를 기다려야 한다면, A무한히 확인하는 것이 아니라, 효율적으로 대기있어야 합니다.

📝 2️⃣ 문제점

  • While Loop대기하는 방식
    • A 스레드가 B 스레드의 작업 완료를 무한 반복(while)으로 확인하는 방식
    • CPU 리소스를 매우 많이 소모하며, 비효율적입니다.

3️⃣ 해결책: Thread.join()

  • Thread.join() 메서드를 사용하면, 다른 스레드가 완료될 때까지 현재 스레드의 실행을 일시 중지합니다.
  • B 스레드가 완료되면 A 스레드가 다시 실행됩니다.
  • Timeout 설정가능하여, 일정 시간만 기다린 진행할 수도 있습니다.

🔄 4️⃣ 코드 예시

📌 Main 클래스

package thread.coordinate;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        List<Long> inputNumbers = Arrays.asList(0L, 3424L, 23543L, 5432L, 123L, 124L, 22L, 13243L);

        List<FactorialThread> threads = new ArrayList<>();

        for (long inputNumber : inputNumbers) {
            threads.add(new FactorialThread(inputNumber));
        }

        for (Thread thread : threads) {
            thread.setDaemon(true);
            thread.start();
        }

        for (Thread thread : threads) {
            thread.join(2000);
        }

        for (int i = 0; i < inputNumbers.size(); i++) {
            FactorialThread factorialThread = threads.get(i);

            if (factorialThread.isFinished) {
                System.out.println("Factorial of " + inputNumbers.get(i) + " is " + factorialThread.getResult());

            } else {
                System.out.println("The calculation for " + inputNumbers.get(i) + " is still in progress");

            }
        }
    }

    public static class FactorialThread extends Thread {
        private long inputNumber;
        private BigInteger result = BigInteger.ZERO;
        private boolean isFinished = false;

        public FactorialThread(long inputNumber) {
            this.inputNumber = inputNumber;
        }

        @Override
        public void run() {
            this.result = factorial(inputNumber);
            this.isFinished = true;
        }

        private BigInteger factorial(long n) {
            BigInteger tempResult = BigInteger.ONE;

            for (long i = n; i > 0; i--) {
                tempResult = tempResult.multiply(new BigInteger(Long.toString(i)));
            }

            return tempResult;
        }

        public boolean isFinished() {
            return isFinished;
        }

        public BigInteger getResult() {
            return result;
        }
    }
}

 

 

출력 결과 : 

🚀 7️⃣ 결론

  • Thread.join()사용하면 CPU 리소스를 낭비하지 않고, 다른 스레드의 작업이 끝날 때까지 효율적으로 대기할 있습니다.
  • Daemon Thread조합하면, 메인 스레드가 종료되면 서브 스레드도 자연스럽게 종료되므로 자원 관리가 효율적입니다.
반응형