Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item 84. 프로그램의 동작을 스레드 스케줄러에 기대지 말라 #106

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Item 84. 프로그램의 동작을 스레드 스케줄러에 기대지 말라

생성 일시: 2023년 1월 2일 오후 9:11

여러 스레드가 실행중이라면 운영체제의 스레드 스케줄러가 어떤 스레드를 얼마나 오래 실행할지를 결정하는데, 정상적인 운영체제라면 이 작업을 공정하게 수행하게 해준다.

그렇지만, 운영체제마다 스케줄링 정책은 다르다. 그래서 잘 작성된 프로그램은 스케줄링에 영향을 받지 않으며 정확성이나 성능이 스케줄러따라 달라져선 안된다.

> 이식성 좋은 프로그램을 만드는 가장 좋은 방법
>

평균적인 실행 가능 스레드 수를 프로세서 수보다 지나치게 많아지지 않도록 하는 것이다.

실행 준비가 된 스레드들은 작업을 완료할 때까지 계속 실행되도록 만들어주자.

→ 스레드 스케줄링 정책이 아주 상이한 시스템에서도 동작이 크게 달라지지 않는다.

실행가능한 스레드 수와 전체 스레드 수는 구분해야 한다.

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

각 스레드가 무언가 유용한 작업을 한 이후에 다음 일거리가 생길 때까지 대기하도록 하는 것

**스레드는 당장 처리해야할 작업이 없다면 실행되선 안된다.**

→ 스레드 풀을 적절하게 설정 후 작업은 짧게 유지하면 됨.

### 바쁜 대기상태가 되지 않아야 한다

공유 객체 상태가 바뀔때까지 쉬지 않고 검사해서는 안된다.

바쁜 대기는 스레드 스케줄러의 변덕에 취약하고, 프로세스에 큰 부담을 준다.

CountDownLatch를 잘못 구현한 코드

```java
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--;
}
}
}
```

하나 이상의 스레드가 필요없이 실행 가능한 상태인 시스템이라면 흔하게 볼 수 있는 과정이다.

이런 시스템은 성능과 이식성이 떨어질 수 있다.

특정 스레드가 다른 스레드들보다 CPU 시간을 충분히 얻지 못하여 간신이 돌아가는 프로그램에도 `Thread.yield` 를 써서 고치려는 유혹을 떨쳐내야 한다.

`Thread.yield` 는 테스트할 수단도 없다.

우선순위를 주는 방법도 있지만, 이마저도 위험이 존재한다.

그리고 스레드 우선순위는 자바에서 이식성이 가장 나쁜 특성에 속한다.

## 정리

단순하게 생각해보면 어떻게 실행되어도 항상 동일한 결과를 나타내주면 된다는 뜻인것 같다.

그래서 스레드를 튜닝할 게 아니라 정말 근본적인 문제가 뭐 때문인지를 파악하는게 중요할 것이다.