Java ‐ 프로그램의 동작을 쓰레드 스케줄러에 기대지 말라[Effective Java Item 84] - thought-corner/Backend-PlayGround GitHub Wiki
쓰레드 스케줄러
- 쓰레드 스케줄러란, 여러 쓰레드가 실행 중이면 운영체제의 쓰레드 스케줄러가 어떤 쓰레드를 얼마나 오래 실행할지 정하는 역할을 한다.
- 쓰레드 스케줄러는 쓰레드의 실행 시점을 관리하는 역할을 한다.
- 언제 실행 가능한 상태로 움직여야할지
- 언제 실행중인 상태를 종료해야할지
- 종료했을때 쓰레드를 어디로 보내야할지
- 사용자가 제어할 수 없다.
- 제한된 자원을 여러 프로세스가 효율적으로 사용하도록 다양한 정책을 가지고 할당한다.
실행 가능한 쓰레드 수를 적게 유지하기 - 당장 처리해야할 작업이 없다면 실행하지 않는다.
- 쓰레드 풀 크기를 적절히 설정하고 작업은 짧게 유지해야 한다.
- 단, 너무 짧으면 오히려 작업 분배에 부담이 가서 성능이 저하될 수 있다.
- 바쁜 대기 상태가 되면 안된다.
// 바쁜 대기 버전 CountDownLatch 구현
public class SlowCountDownLatch {
private int count;
public SlowCountDownLatch(int count) {
if (count < 0) {
throw new IllegalArgumentException(count + " < 0");
}
this.count = count;
}
public void await() { // 바쁜 대기 중 (so bad ~~~)
while (true) {
synchronized (this) {
if (count == 0) {
return;
}
}
}
}
public synchronized void countDown() {
if (count != 0) {
count--;
}
}
}
지양해야 하는 것 1 - Thread.yield()
yield()란, 다른 쓰레드에게 실행을 양보하는 메서드이다.
- 이것을 지양하는 이유는 오히려 성능이 나빠질 수 있기 때문이다. 추가로 테스트할 수단도 없다.
지양해야 하는 것 2 - Thread Priority
- 이미 잘 동작하는 프로그램의 서비스 품질을 높이기 위해서 드물게 쓰일 수는 있다.
- 그러나 거의 동작하지 않는 프로그램을 고치기 위해 사용해선 안 된다.
- 쓰레드 우선순위는 이식성이 가장 나쁜 특성에 속한다.