Thread.sleep()
과 체크 예외개발을 하다 보면 Thread.sleep()
을 사용할 때 체크 예외(Checked Exception)로 인해 코드를 작성하면서 당황했던 경험이 있을 수 있다. 이 글에서는 체크 예외와 Thread.sleep()
의 관계, 그리고 main
메서드에서 예외가 동작하는 방식을 살펴보겠다.
Thread.sleep()
의 기본 개념Thread.sleep()
메서드는 현재 실행 중인 스레드를 일정 시간 동안 대기 상태로 만드는 역할을 한다. 다음은 간단한 예시이다:
public class SleepExample {
public static void main(String[] args) {
try {
System.out.println("Start");
Thread.sleep(1000); // 1초 동안 스레드 멈춤
System.out.println("End");
} catch (InterruptedException e) {
System.out.println("Thread was interrupted!");
}
}
}
Thread.sleep(1000)
: 현재 스레드를 1초(1000ms) 동안 멈춘다.InterruptedException
: 이 메서드는 체크 예외인 InterruptedException
을 던질 수 있다. 이는 try-catch 블록으로 처리하거나, 메서드 선언에 throws
로 명시해야 한다.체크 예외(Checked Exception)는 컴파일러가 강제하는 예외이다. 즉, 예외 처리를 반드시 해야만 컴파일이 성공한다. 대표적인 예로 IOException
, SQLException
, 그리고 InterruptedException
등이 있다.
try-catch
로 예외 처리:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread interrupted!");
}
throws
키워드로 예외 던지기:
public static void main(String[] args) throws InterruptedException {
Thread.sleep(1000);
}
자바의 상속에서 체크 예외는 특정 규칙을 따른다. 부모 클래스의 메서드가 예외를 던지지 않으면, 이를 재정의(override)하는 자식 클래스의 메서드에서도 체크 예외를 던질 수 없다.
class Parent {
public void doSomething() {
// 예외를 던지지 않음
}
}
class Child extends Parent {
@Override
public void doSomething() throws InterruptedException { // 컴파일 에러 발생!
Thread.sleep(1000);
}
}
doSomething()
메서드는 예외를 던지지 않으므로, 자식 클래스도 예외를 던질 수 없다.main
메서드에서는 왜 예외를 던질 수 있을까?main
메서드는 JVM이 직접 호출하는 프로그램의 진입점이다. 따라서 예외 처리를 위해 호출될 상위 메서드가 없으며, 예외가 발생하면 JVM이 직접 처리한다.
throws
선언public class MainExample {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(1000); // 예외를 JVM이 처리
System.out.println("Program continues...");
}
}
throws
로 예외 선언: main
메서드에서 발생한 체크 예외는 JVM이 받아들여 프로그램이 종료되거나 로그로 기록된다.만약 예외가 발생하면, 스택 트레이스와 함께 예외 정보가 출력된다.
Thread.sleep()
와 체크 예외의 실무 활용체크 예외는 예외 처리를 강제함으로써 개발자가 예외 상황을 명확히 인지하고 적절히 대응하도록 돕는다. 그러나 때로는 이런 예외 처리 규칙이 번거로울 수 있다.
일반적인 패턴:
public void pauseThread(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
// 예외 발생 시 스레드 상태 복구 또는 로깅
Thread.currentThread().interrupt(); // 스레드 인터럽트 상태 복구
System.out.println("Sleep was interrupted");
}
}
스레드 인터럽트 처리:
예외가 발생하면 스레드의 인터럽트 상태를 복구하여 정상적인 처리를 이어가는 것이 중요하다.
Thread.sleep()
는 체크 예외를 던지기 때문에 반드시 try-catch 또는 throws로 예외를 처리해야 한다.main
메서드는 프로그램의 진입점으로 JVM이 호출하며, 체크 예외를 자유롭게 던질 수 있다.