[Java] thread - 데몬 쓰레드, 실행 제어

4062 단어 JavaJava

자바의 정석을 통해 공부한 내용을 요약하였습니다.

1. 데몬 쓰레드(daemon thread)

  • 일반 쓰레드의 작업을 돕는 보조적인 역할을 수행하는 쓰레드이다.
  • 일반 쓰레드가 모두 종료되면 데몬 쓰레드는 강제적으로 자동 종료된다.
  • 가비지 컬렉터, 워드프로세서의 자동저장, 화면 자동갱신등이 데몬 쓰레드의 예이다.

boolean isDaemon() - 쓰레드가 데몬 쓰레드인지 확인
void setDaemon(boolean on) - 쓰레드를 데몬 쓰레드로 지정할 때 사용

  • 데몬 쓰레드는 무한 루프와 조건문을 이용해서 실행 후 대기하다가 특정 조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.
  • 데몬 쓰레드 작성 후 setDaemon을 설정하지 않는다면 해당 프로그램은 계속해서 실행상태가 될 것이다.


2. 쓰레드의 실행제어

  • 효율적인 멀티쓰레드 프로그래밍을 위해선 쓰레드가 낭비없이 사용되어야 한다.

2-1. 쓰레드의 상태

  • NEW - 쓰레드가 생성되고 start()가 호출되지 않은 상태
  • RUNNABLE - 실행 중 또는 실행 가능한 상태
  • BLOCKED - 동기화 블럭에 의해서 일시정지된 상태
  • WAITING - 쓰레드가 종료되지 않았지만 실행가능하지 않은 일시정지 상태
  • TIMED_WAITING - 일시정지 시간이 지정된 상태
  • TERMINATED - 쓰레드의 작업이 종료된 상태

2-2. 실행제어 메서드

1) sleep

static void sleep(long millis)
static void sleep(long millis, int nanos)

  • 일정시간동안 쓰레드를 멈추게 한다.
  • static 메서드이기 때문에 현재 쓰레드에서만 사용할 수 있다.
  • sleep()은 지정된 시간이 다 되거나, interrupt()(예외 발생)에 의해 깨어난다.
  • 그래서 항상 try-catch문으로 예외를 처리해야 한다.
void delay(long millis){
	try{
    	Thread.sleep(millis);
    }
    catch(InterruptedException e) {}
}
  • 매번 예외처리하는 것이 번거롭기 때문에 위와 같은 함수를 만들어 사용하기도 한다.

2) interrupt()

void interrupt() - 쓰레드의 interrupted 상태를 true로 변경
boolean isInterrupted() - 쓰레드의 interrupted 상태 반환
static boolean interrupted() - 현재 쓰레드의 interrupted상태 반환 후 false로 변경

  • 대기상태(WAITING)인 쓰레드를 실행대기 상태(RUNNABLE)로 만든다.

3) suspend(), resume(), stop()

void suspend() - 쓰레드를 일시정지 시킴
void resume() - suspend()에 의해 일시정지된 쓰레드를 실행대기 상태로 만듬
void stop() - 쓰레드를 즉시 종료

  • 해당 메서드들은 교착상태(deadlock)을 유발시키기 때문에 사용이 권장되지 않는다.
  • Java API문서 상에서도 Deprecated로 명시되어 있다.

4) join()

void join() - 작업이 모두 끝날때 까지 기다림
void join(long millis) - 지정된 1/1000초 동안 기다림
void join(long millis, int nanos) - 1/1000초, 나노초 동안 기다림

  • 쓰레드 자신이 하던 작업을 멈추고 특정 쓰레드가 지정된 시간동안 작업을 수행하는 것을 기다린다.
  • sleep()과 마찬가지로 interrupt()에 의해 대기상태를 벗어날 수 있어 try-catch문을 사용해야 한다.

5) yield()

  • 남은 시간을 다음 쓰레드에게 양보하고 현재 쓰레드는 실행대기한다.
  • yield()와 interrupt()를 적절히 사용할 시, 응답성과 효율을 높일 수 있다.
  • OS 스케줄러에 통보만 할 뿐 반드시 동작한다는 보장은 없다.
  • 그렇다고 해서 yield()를 쓰는 것이 효과가 없는 것은 아니다.

좋은 웹페이지 즐겨찾기