스레드 생성
Thread
클래스를 상속받아run()
메서드를 오버라이딩하여 스레드를 생성Runnable
인터페이스를 구현하여 스레드를 생성
Thread 클래스 상속
스레드 클래스 정의
public class HelloThread extends Thread {
@Override
public void run() {
doSomething();
}
}
스레드 생성 및 실행
start()
메서드를 호출하여 스레드를 실행- main 스레드와 별도의 스레드를 실행
run()
메서드를 직접 호출하면 main 스레드에서 실행main
스레드는HelloThread
인스턴스에 있는run()
메서드를 호출하는 형태
public class HelloThreadMain {
public static void main(String[] args) {
HelloThread helloThread = new HelloThread();
helloThread.start();
}
}
데몬 스레드
스레드는 사용자(user) 스레드와 데몬(daemon) 스레드로 구분
차이는 JVM 종료 시점
- 모든 user 스레드가 종료되면 JVM도 종료
- 데몬 스레드는 user 스레드가 모두 종료되면 데몬 스레드도 종료 (why? JVM이 종료돼서)
setDaemon(true)
메서드를 호출하여 데몬 스레드로 설정
- 데몬 스레드 여부는
start()
실행 전에 결정 (이후에 수정 불가)
public class DaemonThreadMain {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": main() start");
DaemonThread daemonThread = new DaemonThread();
daemonThread.setDaemon(true); // 데몬 스레드 여부
daemonThread.start();
System.out.println(Thread.currentThread().getName() + ": main() end");
}
static class DaemonThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": run()");
try {
Thread.sleep(10000); // 10초간 실행
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": run() end");
}
}
}
run()
메서드 안에서 Thread.sleep()
를 호출할 때 checked exception 인 InterruptedException
을 밖으로 던질 수 없고 반드시 잡아야 함
- why?
run()
메서드는 부모 클래스Thread
의 인터페이스인Runnable
인터페이스에서 throws를 선언하지 않고 있음- 자바 오버라이드 규칙에 따라 부모 메서드 또는 인터페이스가 체크 예외를 던지지 않는 경우, 재정의된 자식 메서드도 체크 예외를 던질 수 없음
InterruptedException
은 checked exception 이기 때문에try-catch
블록으로 예외를 잡아야 함
Runnable 인터페이스 구현
Runnable
인터페이스를 구현하는 방식으로 스레드를 생성
public interface Runnable {
void run();
}
public class HelloRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": run()");
}
}
Thread 상속 vs Runnable 구현
스레드 사용할 때는 Thread 를 상속 받는 방법보다 Runnable 인터페이스를 구현하는 방식을 사용하자
- 자바는 다중 상속이 안 된다 -> Thread 클래스를 상속받으면 다른 클래스를 상속받을 수 없음
- 코드의 분리가 안 된다 -> 굳이
Thread
클래스를 상속받아서 디펜던시 및 추가적인 메모리를 할당 할 필요가 없음 - 여러 스레드가 동일한
Runnable
객체를 공유할 수 있어 자원 관리를 효율적으로 할 수 있다 ->Runnable
인스턴스를 여러 스레드에서 사용할 수 있음 (개별 스레드에서run()
참조 값이 같음)
'Java > 멀티스레드' 카테고리의 다른 글
[JAVA] 스레드 제어와 생명주기 (0) | 2024.09.18 |
---|