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

섹션 3: 스레딩 기초 - 스레드 조정

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

💡 Java에서 스레드를 정지하는 방법과 Interrupt필요성


🔍 1️⃣ 스레드 정지가 필요한 이유

  • 스레드는 아무것도 하지 않아도 메모리와 커널 리소스사용합니다.
  • CPU 시간과 캐시 공간소모하기 때문에, 작업이 끝난 스레드는 정리하는 것이 좋습니다.
  • 특히, 메인 스레드종료되어도 다른 스레드가 살아있으면 어플리케이션은 계속 실행됩니다.
  • 예기치 않은 오류나 무한 루프에 빠진 스레드가 존재하면, 리소스 낭비가 발생합니다.

🔄 2️⃣ Thread.interrupt()역할

  • interrupt() 메서드는 스레드에 인터럽트 플래그설정합니다.
  • 플래그를 확인하여 스레드가 멈추거나 특정 로직을 수행하도록 유도합니다.
  • 특히, Blocking 상태 (예: sleep, wait, join)에서는 InterruptedException발생하며 빠져나올 있습니다.

📝 3️⃣ 예시 코드: Blocking 상태에서 interrupt 사용하기

package thread.interrupt;

public class Main {

    public static void main(String[] args) {
        Thread thread = new Thread(new BlockingTasks());

        thread.start();

        thread.interrupt();

    }

    private static class BlockingTasks implements Runnable {

        @Override
        public void run() {
            try {
                Thread.sleep(500000);
            } catch (InterruptedException e) {
                System.out.println("Exiting blocking thread");
            }
        }
    }
}

 

🎯 4️⃣ 실행 결과

Exiting blocking thread
  • Thread.sleep(500000);500동안 스레드를 멈추게 합니다.
  • 하지만 thread.interrupt();호출되면서 InterruptedException발생하고, "Exiting blocking thread" 메시지가 출력됩니다.
  • 즉시 run() 메서드의 catch 블록으로 넘어가며 정상 종료됩니다.

📝 3️⃣ 예시 코드: Blocking 상태에서 interrupt 사용하기

package thread.interrupt2;

import java.math.BigInteger;

public class Main {

    public static void main(String[] args) {

        Thread thread = new Thread(new LongComputationTask(new BigInteger("2"), new BigInteger("10")));

        thread.start();
        thread.interrupt();

    }

    private static class LongComputationTask implements Runnable {
        private BigInteger base;
        private BigInteger power;

        public LongComputationTask(BigInteger base, BigInteger power) {
            this.base = base;
            this.power = power;
        }

        @Override
        public void run() {
            System.out.println(base + " ^ " + power + " = " + pow(base, power));
        }

        private BigInteger pow(BigInteger base, BigInteger power) {
            BigInteger result = BigInteger.ONE;

            for (BigInteger i = BigInteger.ZERO; i.compareTo(power) != 0; i = i.add(BigInteger.ONE)) {

                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("interrupted computation");
                    return BigInteger.ZERO;
                }

                result = result.multiply(base);
            }

            return result;
        }
    }

}

 

 

💡 JavaDaemon Thread (데몬 스레드)


🔍 1️⃣ Daemon Thread란?

  • 백그라운드에서 동작하는 스레드로, 애플리케이션의 주요 작업을 보조하는 역할을 합니다.
  • 일반적으로 쓰레기 수집(Garbage Collection), JVM 메모리 관리 같은 작업에 사용됩니다.
package thread.interrupt3;

import java.math.BigInteger;

public class Main {

    public static void main(String[] args) {

        Thread thread = new Thread(new LongComputationTask(new BigInteger("2"), new BigInteger("10")));

        thread.setDaemon(true);

        thread.start();
        thread.interrupt();

    }

    private static class LongComputationTask implements Runnable {
        private BigInteger base;
        private BigInteger power;

        public LongComputationTask(BigInteger base, BigInteger power) {
            this.base = base;
            this.power = power;
        }

        @Override
        public void run() {
            System.out.println(base + " ^ " + power + " = " + pow(base, power));
        }

        private BigInteger pow(BigInteger base, BigInteger power) {
            BigInteger result = BigInteger.ONE;

            for (BigInteger i = BigInteger.ZERO; i.compareTo(power) != 0; i = i.add(BigInteger.ONE)) {

                result = result.multiply(base);
            }

            return result;
        }
    }

}

🚀 7️⃣ Daemon Thread 활용 예시

  • 로그 기록 쓰레드
  • 백그라운드 데이터 동기화
  • Heartbeat (서버 상태 확인)
반응형