Thread (3)

김재익·2023년 6월 19일
0

JAVA

목록 보기
11/18
post-thumbnail

쓰레드는 걸리는 시간이나 동작을 예측할 수가 없다.

데몬 쓰레드

background에서 실행되는 낮은 우선순위를 가진 쓰레드
보조적인 역할을 담당하며 대표적인 데몬 스레드로는 메모리 영역을 정리해주는 가비지 컬렉터(GC)가 있다.

public class Main {
    public static void main(String[] args) {
        Runnable demon = () -> {
            for (int i = 0; i < 1000000; i++) {
                System.out.println("demon");
            }
        };

        Thread thread = new Thread(demon);
        thread.setDaemon(true); // true로 설정시 데몬스레드로 실행됨

        thread.start();

        for (int i = 0; i < 100; i++) {
            System.out.println("task");
        }
    }
}

데몬 쓰레드가 맡은 기능이 수행되는 도중에 메인쓰레드의 일이 끝나 메인쓰레드가 끝나면 데몬 쓰레드의 남은 기능은 수행되지않고 종료된다. (JVM에 의해 종료된다)

우선순위

쓰레드 작업의 중요도에 따라서 쓰레드의 우선순위를 부여할 수 있다.
우선순위는 직접 지정하거나 JVM에 의해 결정된다.

우선순위는 아래와 같이 3가지 (최대/최소/보통) 우선순위로 나뉜다.

  • 최대 우선순위 (MAX_PRIORITY) = 10
  • 최소 우선순위 (MIN_PRIORITY) = 1
  • 보통 우선순위 (NORM_PRIORITY) = 5
    • 기본 값이 보통 우선순위이다.
  • 이 우선순위는 OS가 아닌 JVM에서 설정하는 것이다.
public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                System.out.print("$");
            }
        };
        Runnable task2 = () -> {
            for (int i = 0; i < 100; i++) {
                System.out.print("*");
            }
        };


        Thread thread1 = new Thread(task);
        thread1.setPriority(8);
        int threadPriority = thread1.getPriority();
        System.out.println("threadPriority = " + threadPriority);

        Thread thread2 = new Thread(task2);
        thread2.setPriority(2);

        thread1.start();
        thread2.start();
    }
}

쓰레드 그룹

서로 관련이 있는 쓰레드들을 그룹으로 묶어서 다룰 수 있다.

  • JVM이 시작되면 system그룹이 생성되고 쓰레드 들은 기본적으로 system 그룹에 포함된다.
  • 모든 쓰레드들은 반드시 하나의 그룹에 포함되어야 한다.
    • 쓰레드 그룹을 지정받지 못한 쓰레드는 자신을 생성한 부모 쓰레드의 그룹과 우선순위를 상속받게 된다. 우리가 생성한 쓰레드들은 main 쓰레드 하위에 포함된다.
    • 쓰레드 그룹을 지정하지 않으면 해당 쓰레드는 자동으로 main 그룹에 포함된다.
  • 메인 쓰레드는 system그룹 하위에 있는 main 그룹에 포함된다.
public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    break;
                }
            }
            System.out.println(Thread.currentThread().getName() + " Interrupted");
        };

        // ThreadGroup 클래스로 객체를 만듭니다.
        ThreadGroup group1 = new ThreadGroup("Group1");

        // Thread 객체 생성시 첫번째 매개변수로 넣어줍니다.
        // Thread(ThreadGroup group, Runnable target, String name)
        Thread thread1 = new Thread(group1, task, "Thread 1");
        Thread thread2 = new Thread(group1, task, "Thread 2");

        // Thread에 ThreadGroup 이 할당된것을 확인할 수 있습니다.
        System.out.println("Group of thread1 : " + thread1.getThreadGroup().getName());
        System.out.println("Group of thread2 : " + thread2.getThreadGroup().getName());

        thread1.start();
        thread2.start();

        try {
            // 현재 쓰레드를 지정된 시간동안 멈추게 합니다.
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // interrupt()는 일시정지 상태인 쓰레드를 실행대기 상태로 만듭니다.
        group1.interrupt();

    }
}
profile
개발자호소인

0개의 댓글