스레드 스케줄러와 Thread.yield, 스레드 우선순위에 의존하지 말자. 견고성과 이식성을 모두 해치는 행위이다.
스레드 우선순위는 프로그램의 서비스 품질을 높이는데 드물게 쓰일 수는 있지만 프로그램을 고치는 용도로 사용해서는 안된다.
• 정확성이나 성능이 운영체제 고유의 스레드 스케줄러에 따라 달라지는 프로그램일수록 다른 플랫폼에 이식하기 어렵다.
• 견고하고 이식성 좋은 프로그램을 작성하기 위해서 고려해야 할 것들
◦ 실행 가능한 스레드의 평균 개수를 프로세서 수 보다 지나치게 많아지지 않도록 관리할 것
◦ 즉 실행가능한 스레드 수를 가능한 적게 유지하는 것이 중요하다.
실행 가능한 스레드 수를 적게 유지하는 방법
• 실행 준비가 된 스레드들은 맡은 작업을 완료할 때 까지 계속 실행되도록 할 것
◦ 단 실행 가능한 스레드 수 와 전체 스레드 수는 구분해야 한다. (대기 중인 스레드 = 실행 불가)
• 스레드는 당장 처리해야 할 작업이 없다면 실행 되어서는 안된다.
• 스레드는 Busy Waiting 상태가 되면 안된다.
◦ Busy Waiting 상태
- 스레드 스케줄러 환경의 변화에 취약하다. (이식성이 낮다)
- 프로세서에 부담을 주어 다른 작업이 실행의 기회를 박탈당한다. (성능이 낮다)
- Busy Waiting이 발생하는 코드 예시 (작가평 : 끔찍한 코드이다!)
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 : 다른 스레드에게 실행을 양보하는 메서드
◦ 실행 중인 스레드를 RUNNABLE (실행 대기) 상태로 바꾼다.
- 스레드가 실행되었는데, 그 실행이 잠시동안 무의미한 경우가 있을 수 있다.
- 이런 경우 스레드를 잠시 실행 대기 상태로 돌려놓으면 CPU의 자원의 소모를 방지할 수 있다.
- 이 때 Thread.yield 메소드가 유용하게 사용될 수 있다.
• 특정 스레드가 다른 스레드에 비해 CPU 자원을 할당받지 못하는 경우에도 Thread.yield 사용은 지양하자
◦ 증상이 호전될 수 있어도 여전히 이식성이 나쁘다
- JVM 종류에 따라 차이가 미미할수도, 악화될수도 있다.
• 차라리 어플리케이션 구조를 바꿔 동시에 실행 가능한 스레드 수를 줄이는 것이 좋다.
스레드 우선순위 조정에 주의하라
• 스레드 우선순위는 자바에서 이식성이 가장 나쁜 특성 중 하나이다.
◦ A 타입의 JVM 에서 1-2-3 의 순서로 실행되었다고 하더라도, B 타입의 JVM에서 동일한 순서로 실행되리라는 보장이 없다.
- A 타입에서 1-2-3 의 순서로 실행된 것이 B 타입의 JVM 에서는 3-1-2 의 순서로 실행될 수 있음
- 즉 1-2-3 이 최적의 성능을 보장하는 우선순위 였다고 해도, 다른 JVM 에서 3-1-2 의 순서로 실행되어 버리면 다시 성능이 나빠진다.
• 특히 응답 불가 문제는 스레드 우선순위로 해결해선 안된다.
◦ 진짜 원인을 찾아 수정하기 전까지 같은 문제가 반복해서 발생할 것이다.
'Java' 카테고리의 다른 글
[Clean Architecture] 4. 유즈케이스 구현하기 (0) | 2023.02.20 |
---|---|
[Effective Java] ITEM87 : 커스텀 직렬화 형태를 고려해보라 (0) | 2022.11.28 |
[Effective Java] ITEM74 : 메서드가 던지는 모든 예외를 문서화하라 (0) | 2022.11.06 |
[Effective Java] ITEM69 : 예외는 진짜 예외 상황에만 사용하라 (0) | 2022.09.20 |
[Effective Java] ITEM64 : 객체는 인터페이스를 사용해 참조하라 (0) | 2022.09.20 |