Java - 데몬 쓰레드, 쓰레드의 상태, 쓰레드의 실행제어 메서드

춤추는개발자·2022년 12월 12일
0

Java 정리

목록 보기
58/59

쓰레드에는 일반 쓰레드와 데몬 쓰레드가 있다. 데몬 쓰레드를 알아보자.

데몬 쓰레드

  • 일반 쓰레드의 작업을 돕는 보조적인 역할을 수행한다.
  • 일반 쓰레드가 모두 종료되면 자동적으로 종료된다.
  • 데몬 쓰레드의 예로는 가비지 컬렉터, 자동저장, 화면자동갱신 등에 사용된다.
  • 무한루프와 조건문을 이용해서 실행 후 대기하다가 특정조건이 만족되면 작업을 수행하고 다시 대기하도록 작성한다.
boolean isDaemon() : 쓰레드가 데몬 쓰레드인지 알려주는 역할을 한다.
데몬 쓰레드이면 true를 반환한다.
void setDaemon(boolean on) : 쓰레드를 데몬 쓰레드로 또는 사용자 쓰레드로 변경할때 사용한다. 매개변수를 true로 지정하면 데몬 쓰레드가 된다.
  • setDaemon(boolean on)을 사용할때 반드시 start()를 호출하기 전에 실행해야 한다. 그렇지 않으면 IllefalThreadStatrException 오류가 발생한다. 쓰레드를 생성해서 실행한 후에는 쓰레드를 변경할 수 없다.

쓰레드의 상태

NEW : 쓰레드가 생성되고 아직 start()가 호출되지 않은 상태이다.
RUNNABLE : 실행 중 또는 실행 가능한 상태
BLOCKED : 동기화블럭에 의해서 일시정지된 상태이며 lock이 풀릴때까지 기다리는 상태이다.
WATING, TIMED_WATING : 쓰레드의 작업이 종료되지는 않았지만 실행가능하지 않은 일시정지상태이다. TIMED_WATINGd은 일시정지 시간이 지정된 경우를 의미한다.
TERMINATED : 쓰레드의 작업이 종료된 상태

쓰레드의 실행제어

  • 쓰레드의 실행을 제어할 수 있는 메서드가 제공된다. 이 메서드들을 적절히 활용해서 효율적인 프로그램을 작성해야한다.

쓰레드의 스케줄링과 관련된 메서드

sleep() (static 메서드)

  • 현재 쓰레드를 지정된 시간동안 멈추게 한다. static 메서드라서 항상 현재 쓰레드에만 동작한다.

    static void sleep(long millis) // 천분의 1초 단위
    static void sleep(long millis, int nanos) // 천분의 1초 + 나노초

    위와 같이 나노초까지 값을 지정할 수 있지만 어느정도 오차가 있다는것을 염두해 둬야 합니다.

  • sleep()에 의해서 일시정지 상태가 된 쓰레드는 지정된 시간이 다 되거나 interrupt()가 호출되면 잠에서 꺠어나 실행대기 상태가 됩니다.

  • sleep()를 호출할 때는 항상 try-catch문으로 예외를 처리해줘야 합니다. 그 이유는 InterruptedException이 발생하면 깨어나기 때문입니다.
    InterruptedException은 Exception의 자손이기 때문에 항상 예외처리를 해줘야 합니다.
    하지만 항상 예외처리를 해주는것이 어렵기 때문에 sleep()를 호출하고 예외처리가 된 메서드를 재정의해서 사용하는것도 좋은방법 입니다.

  • 특정 쓰레드를 지정해서 멈추게 하는 것은 불가능하다. sleep() 메서드는 자기 자신한테 적용되는 메서드이다.

    interrupt()

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

    void interrupt() : 쓰레드의 interrupted 상태를 false에서 true로 변경 해준다.
    boolean isInterrupted() : 쓰레드의 interrupted 상태를 반환 해준다.
    static boolean interrupted() : 현재 쓰레드의 interrupted 상태를 반환해주고 false로 초기화 해준다.

    interrupted() 메서드는 static이기 때문에 현재 그 쓰레드의 상태를 반환해주고 false로 초기화 해주는것을 꼭 기억해야 합니다.

    suspend(), resume(), stop()

  • 쓰레드의 실행을 일시정지 (suspend() ), 재개(resume()), 완전정지(stop()) 시키는 메서드 입니다.

    void suspend() : 쓰레드를 일시정지 시킨다. 웨이팅 상태가 된다. 
    void resume() : suspend()에 의해 일시정지된 쓰레드를 실행대기 상태로 만든다.
    void stop() : 쓰레드를 즉시 종료시킨다.

    위의 세가지 메서드들을 이용하면 쓰레드를 제어하기 쉽다. 하지만 suspend(), stop()이 교착상태가 발생할 가능성이 있어서 권장되지 않는다. 현재 Java API 문서에서는 이 메서드들은 deprecated 되었다.

    deprecated란?
    전에는 사용되었지만, 앞으로 사용하지 않을 것을 권장한다는 뜻이다. 사용이 불가한것은 아니지만 이 메서드들을 deprecated 하였는데 Java 문법에서 삭제하지 않은 이유는 하위 호완성을 위해서 삭제하지 않은 것 뿐이다. 결론적으로 사용하지 않는 것이 좋다.

    join()

  • 지정된 시간도안 특정 쓰레드가 작업하는 것을 기다린다.

    void join() // 작업이 모두 끝날때까지 
    void join(long millis) // 천분의 1초 동안 
    void join(long mills, int nanos) // 천분의 1초 + 나노초 동안
  • 사용할때 예외처리를 해줘야 한다. (InterruptedException이 발생하면 작업을 재개 합니다.)

  • sleep()와 유사하지만 다른점은 현재 쓰레드가 아닌 특정 쓰레드에서 동작하고 static 메서드가 아니라는 점이다.

    yield()

  • 남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 쓰레드)는 실행대기 하는 메서드 입니다. static 메서드이다.

  • yield()와 interrupt()를 적절히 사용하면 응답성과 효율을 높일 수 있습니다.

  • yield()는 os스케줄러한테 알려주는것이기 때문에 반드시 동작한다는 보장이 없다.

0개의 댓글