데몬쓰레드는 다른 일반쓰레드의 작업을 돕는 보조 쓰레드 이다.
일반 쓰레드가 종료되면 데몬 쓰레드는 강제적으로 자동 종료 된다.(보조니까)
데몬 쓰레드는 일반 쓰레드와 실행방법과 작성방법이 같다. 다만 쓰레드를 생성한 다음 실행하기전에 setDaemon(true)를 호출하기만 하면 된다.
데몬쓰레드가 생성한 쓰레드는 자동으로 데몬 쓰레드가 된다.
boolean isDaemon() =쓰레드가 데몬인지 확인한다//데몬이면 true
void setDaemon(boolean on)= 쓰레드를 데몬 쓰레드로 또는 사용자 쓰레드로 변경한다
3초마다 변수 autoSave의 값을 확인해서 그값이 true 이면 autoSave()를 호출하는 일을 무한히 반복하는 쓰레드이다.
만약 이쓰레드를 데몬 쓰레드로 지정하지 않았더라면 무한루프 로 돌것이다.
메인 메서드에서 데몬 쓰레드를 만들고 start() 로 호출스택에 쓰레드를 생성한뒤 main은 main끼리 데몬 쓰레드는 자기들끼리 진행된다.
setDaemon()은 반드시 start()하기전에 실행 되어야한다.
위의 예제는 main 쓰레드 / 데몬 쓰레드 가 따로 따로 돈다고 보면 된다.
=> 프로그램을 실행하면 JVM 은 가비지 컬렉션, 이벤트처리, 그래픽처리와 같이 프로그램이 실행되는 데 필요한 보조작업을 수행하는 데몬 쓰레드들을 자동적으로 생성해서 실행 시킨다. 이들은 SYSTEM쓰레드 또는 MAIN 쓰레드 그룹에 속한다.
쓰레드를 생성하고 Start() 호출하면 바로 실행이 되는게 아니라 대기 상태에 들어간다. 실행 대기열은 큐와 같은 구조로 FIFO이다.
자기 차례가 되면 실행된다.
실행시간이 다되거나 Yield() 를 만나면 다시 실행 대기 상태가 된다.
실행중에 이 메서드들을 만나면 일시 정지상태가 될수 있다. 정지 상태가 끝나면 다시 실행대기 상태가 된다
일시정지 시간이 다되거나 이 메서드들이 호출되면 일시정지 상태에서 벗어나 다시 실행 대기 상태로 돌아간다.
실행을 모두 마치거나 stop()를 만나면 쓰레드는 소멸된다.
(책에 잘 정리되 있어서 참고 했습니다. 저는 누구에게 보여주는용이 아닌 개인 공부용으로 블로그 작성하는거라 깔끔하지 못한점은 이해해 주세요)
Sleep(long mills) =일정시간 동안 쓰레드를 멈추게 한다.
static void sleep(long mills) //static = 자기자신
static void sleep(long mills,int nanos) //static = 자기자신
sleep()에 의해 일시정지 상태가 된 쓰레드는 지정된 시간이 다되거나 interrupt()가 호출되면(InterruptedException 발생), 잠에서 깨어나 실행대기 상태가 된다.(실행 x)
sleep 떄는 항상 try- catch 해주기!
th1. sleep 를 해서 th1이 가장 늦게 종료 될것 같지만 아니다
sleep()이 항상 현재 실행 중인 쓰레드에 대해 작동하기 떄문에 th1.sleep(2000)과 같이 호출 하였어도 실제로 영향을 받는것은 그 메서드를 돌린놈(main쓰레드) 가 잠든것이다.
진행 중인 쓰레드의 작업이 끝나기 전에 취소 시켜야 할때
단지 멈추라는것뿐 종료시키는것은 아니다.
interrupt 는 그저 쓰레드의 interrupted상태(인스턴스 변수) 를 바꾸는 것뿐
interrupt() 를 호출하면 interruptException이 발생되고 쓰레드의 interrupted 상태는 true로 자동 초기화
void interrupt() = 쓰레드의 interruptedtkdxofmf false 에서 true로 전환
boolean isInterrupted() = 쓰레드의 interrupted상태 반환
static boolean interrupted() =현재 쓰레드(자기자신)의 interrupted상태를 반환후, false 로 변경
yield() 는 쓰레드 자신에게 주어진 실행시간을 다음 차례의 쓰레드에게 양보한다.
yield() 와 interrupt() 를 적절히 사용하면 프로그램의 응답성을 높이고 보다 효율적인 실행이 가능하다.
yield 부분이 없고 suspended 가 true 이면 쓸데없이 while문만 도는 busy wating 발생
yield를 호출하여 남은 실행시간을 while문에서 낭비하지 않고 다른 쓰레드에게 양보한다.
다른 쓰레드의 작업을 기다린다.
sleep 처럼 interrupt()에 의해 대기상태에서 벗어 날수있으며, join()이 호출 되는 부분을 try-catch로 감싸야한다.
try{
th1.join() // 현재 실행중인 쓰레드가 쓰레드 thi1의 작업이 끝날때까지 기다린다.
} catch (InterruptedException e){}