Skip to content

[ Item 84 ] 프로그램의 동작을 스레드 스케줄러에 기대지 말자 #84

@kmswlee

Description

@kmswlee

프로그램의 동작을 스레드 스케줄러에 기대하지 마라

  • 스케줄링 정책은 운영체제마다 다를 수 있다.
  • 따라서 잘 작성된 프로그램이라면 이 정책에 좌지우지돼서는 안 된다.
  • 정확성이나 성능이 스레드 스케줄러에 따라 달라지는 프로그램이라면 다른 플랫폼에 이식하기 어렵다

실행 가능한 스레드 수를 적게 유지하는 주요 기법

  • 각 스레드가 무언가 유용한 작업을 완료한 후에는 다름 일거리가 생길 때까지 대기하도록 하는 것이다.
  • 스레드는 당장 처리해야 할 작업이 없다면 실행돼서는 안 된다.
  • 스레드는 절대 바쁜 대기(busy waiting) 상태가 되면 안 된다. 공유 객체의 상태가 바뀔 때까지 쉬지 않고 검사해서는 안 된다는 뜻이다.
  • 바쁜 대기는 스레드 스케줄러의 변덕에 취약할 뿐 아니라, 프로세서에 큰 부담을 주어 다른 유용한 작업이 실행될 기회를 박탈한다.

ex) 피해야 될 극단적인 코드

public class SlowCountDownLatch {
  private int count;

  public SlowCountDownLatch(int count) {
    if (count < 0) 
      throw new IllegalArgumentException(count+"< 0");
    this.count = count;
  }

  public void await() {
    while (true) {
      synchronized(this) {
        if (count == 0)
          return;
      }
    }
  }

  public synchronized void countDown() {
    if (count != 0)
      count--;
  }
}

Thread.yield를 써서 문제를 고쳐보려는 유혹을 떨쳐내자

  • Thread.yield는 테스트할 수단도 없다.
  • 차라리 어플리케이션 구조를 바꿔 동시에 실행 가능한 스레드 수가 적어지도록 조치해주자
  • 스레드 우선순위는 자바에서 이식성이 가장 나쁜 특성에 속한다.
  • 스레드 우선순위를 조율해서 어플리케이션의 반응 속도를 높이는 것도 타당할 수 있으나, 정말 그래야 할 상황은 드물고 이식성이 떨어진다.
  • 심각한 응답 불가 문제를 스레드 우선순위로 해결하려는 시도는 절대 합리적이지 않다.

핵심 정리

  • 프로그램의 동작을 스레드 스케줄러에 기대지 말자.
  • Thread.yield와 스레드 우선순위에 의존해서도 안 된다.
  • 스레드 우선순위는 간신히 동작하는 프로그램을 고치는 용도로 사용해서는 절대 안 된다.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions