CH13-28,29 join90, yield()
[자바의 정석 - 기초편] ch13-28,29 join(), yield()
예제를 보자.
public class EX13_21 {
static long startTime = 0;
public static void main(String[] args) {
ThreadEx21_1 th1 = new ThreadEx21_1();
ThreadEx21_2 th2 = new ThreadEx21_2();
th1.start();
th2.start();
startTime = System.currentTimeMillis();
try {
th1.join();
th2.join();
} catch (InterruptedException e) {}
System.out.println("소요시간:" + (System.currentTimeMillis() - EX13_21.startTime));
}
}
class ThreadEx21_1 extends Thread {
public void run() {
for(int i = 0; i < 300; i++) {
System.out.print(new String("-"));
}
}
}
class ThreadEx21_2 extends Thread {
public void run() {
for(int i = 0; i < 300; i++) {
System.out.print(new String("|"));
}
}
}
main메서드내에서 th1.join()
과 th2.join()
을 실행해 메인 쓰레드가 각각 th1과 th2가 마치기까지를 기다리게끔 했다. 이후에 소요시간을 계산해서 th1과 th2를 마치는데 소요된 시간을 출력하게 했음.
어떤 쓰레드가 할당받은 타임슬라이스 중.. 남은 시간을 포기하고, 자신의 차례를 다음 쓰레드에게 넘긴다. 자신은 실행대기 상태로 돌아간다.
yield도 static메서드이다. 자기 자신에게만 사용가능하다.
언제쓰는가?
예전에 busy wait이라는걸 배웠던게 기억나는가? 어떤 함수가 while문으로 특정한 작업을 하도록 되어있는데, while문 안의 특정한 조건때문에 사실 반복만 할 뿐 실질적으로 아무런 작업을 하지 않는 경우가 있을 수 있다. 위는 세마포어때 배웠던 내용인 것 같은데, 세마포어도 lock일경우에 lock값만 확인하지 while문이 반복되면서 실질적으로 이뤄지는 작업은 없다. 이럴때 바로 yield()로 자원을 양보하면 효율적인 프로그램 구성이 된다.
yield()와 interrupt()를 적절히 사용하면 프로그램의 응답성과 효율을 높일 수 있다.
보통 쓰레드를 구성할때 sleep()을 1이라도 준다. 이는 특정 스레드가 자원을 독점하는 것을 방지하기 위함임. 따라서 어떤 쓰레드를 사용하려고 하면 그 쓰레드가 우연찮게 sleep상태일 수도 있다. 이때 응답성을 높이기 위해 곧바로 interrupt해주는 경우가 일반적이다.
위의 방식대로 짠 코드이다. stop true로 바꿔주는 것 뿐만 아니라, 혹시 sleep()중이었다면 바로 작업할 수 있게 인터럽트까지 시켜주고 있다. 이게 프로그램의 응답성을 높여준다. 이게 없으면 stop눌렀는데 재수없으면 sleep시간 이후에 stop이 될 수도 있다.