계산기 과제로 불탔던 머리도 식힐겸 지난 강의에서 다뤘던 Thread에 대해서 정리해보는 하루를 가져보자.
Thread란 쉽게 말해 프로세스를 실행하기 위한 실행 단위? 라고 할 수 있겠다.
강의에서는 일꾼이라고 표현하는데 그 말이 딱 맞는 것 같다.
프로세스 안에서 하나의 쓰레드만 실행
main()
메서드만 실행시켰을 때 이것을 싱글 쓰레드 라고 합니다.main()
메서드의 쓰레드를 ‘메인 쓰레드’ 라고 부릅니다.프로세스 안에서 여러개의 쓰레드가 실행
📌 Java에서 제공하는 Thread 클래스를 상속받아 쓰레드를 구현
<public class TestThread extends Thread {
@Override
public void run() {
// 쓰레드 수행작업
}
}
...
TestThread thread = new TestThread(); // 쓰레드 생성
thread.start() // 쓰레드 실행
여기서 핵심은 run()
메서드.
run()
메서드에 작성된 코드가 쓰레드가 수행할 작업이다.
📌Java에서 제공하는 Runnable 인터페이스를 사용하여 쓰레드를 구현
<public class TestRunnable implements Runnable {
@Override
public void run() {
// 쓰레드 수행작업
}
}
...
Runnable run = new TestRunnable();
Thread thread = new Thread(run); // 쓰레드 생성
thread.start(); // 쓰레드 실행
위의 경우는, Thread를 직접 받아 상속하는 경우.
이 경우는 Runnable 인터페이스를 통해 구현하는 경우.
확장성을 위해서 인터페이스를 통한 구현이 매우 유리하다.
사용자스레드(user thread)는 foreground에서 실행되는 높은 우선순위를 가진 스레드입니다. 자바 프로그램을 실행시키면 JVM은 main()메서드가 실행되는 main스레드를 생성하는데 이 main스레드가 사용자스레드입니다. 그리고 main스레드에서 새로운 스레드를 생성하게 되면 부모 스레드의 속성을 상속받아 기본적으로 사용자스레드가 되며, 이렇게 생성된 사용자스레드들이 모두 종료하게 되면 그 프로그램은 종료하게 됩니다.
데몬스레드(daemon thread)는 background에서 실행되는 낮은 우선순위를 가진 스레드입니다. 주로 보조적인 역할을 담당하는데 사용되며, 자바에서 메모리 정리를 해주는 가비지 컬렉터(garbage collector)가 대표적인 데몬스레드입니다. 데몬스레드와 사용자스레드의 가장 큰 차이점은 JVM이 데몬스레드가 작업이 끝날때까지 기다리지 않는다는 점입니다. 사용자스레드가 모두 종료되면 데몬스레드는 자동으로 종료됩니다.
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");
}
}
}
데몬 쓰레드에는 for문이 백만번으로 설정 되어 있지만, 사용자 쓰레드인 main 쓰레드가 100번 for문을 반복하면 따라서 종료되게 된다.
📌 쓰레드 작업의 중요도에 따라서 쓰레드의 우선순위를 부여할 수 있습니다.
: 작업의 중요도가 높을 때 우선순위를 높게 지정하면 더 많은 작업시간을 부여받아 빠르게 처리될 수 있습니다.
최소 우선순위 (MIN_PRIORITY) = 1 << 보통 우선순위 (NROM_PRIORITY) = 5
<< 최대 우선순위 (MAX_PRIORITY) = 10
생성 시 기본 값(default)은 보통 우선순위