JAVA/Effective Java

규칙 72 - 스레드 스케줄러에 의존하지마라.

반응형

실행해야 할 스레드가 많을 경우 어떠한 스레드를 얼마나 오랫동안 실행할지 결정은 스레드 스케줄러가 진행한다.

운영체제마다 스레드 스케줄러는 다르기 때문에 아무리 운영체제에서 효율적으로 진행한다고 하더라고 이에 의존하여 프로그램을 제작해서는 안된다.

정확하고 좋은 스레드 프로그램은 의존하는것이 아니라 실행가능한 스레드의 개수가 프로세수 개수보다 넘지 않도록 제작하는 것이다.

그렇게되면 스레드 스케줄러가 순차적으로 스레드를 실행시켜줄뿐 정책에 신경쓰지않는다.

그렇다면 실행중인 스레드의 개수를 최대한 줄일 수 있는 방법은 무엇일까?

바로 사용하지 않는 스레드는 실행하지 않고 정지하거나 종료해야한다. 그래서 바로 직전에 공부했던 스레드 풀을 사용하여 적절하게 스레드를 관리하면 좋은 프로그램을 만들 수 있다.

그렇다면 오래 반환하지 않고 잘못된 스레드 방식으로 개발하는 코드를 알아보자.

public class FailLatch {
	private int count;
	public FailLatch (int count) {
		if (count < 0) {
			throw new IllegalArgumentException(count + " < 0");
		}
		this.count = count;
	}
	
	public void await() {
		while (true) {
			synchronized (this) {
				if (count == 0) {
					System.out.println("the end");
					return;
				}
					
			}
		}
	}
	
	public synchronized void countDown() {
		if (count != 0) {
			count--;
		}
	}

}

 위의 코드를 보면 count가 0일 때까지 스레드가 놀고있어야 하는 아주 좋지 않은 프로그램이 된다. 만약 그럼 저상태에서 대기상태에서 Thread.yield를 사용한다면 조금 나아지려나?

그렇지 않다. 왜냐하면 이는 일부 JVM에서는 성능이 향상되는 것처럼 보일 수 있으나, 무조건 좋아지지 않는다. 그렇기 때문에 병렬적으로 실행 가능한 스레드 수를 애초에 줄이는것이 중요하다.

결론을 이야기하자면 프로그램의 정확성을 스레드 스케줄러에 의존하지말고 쓰레드 수를 제한하고 일부 쓰레드가 무조건 낭비되구 있는것을 방지하자. 단 Thread.yield 등과 같이 임시방편으로 무엇을 해결하려 하지 말고 근본적 문제를 해결하라.

 

출처 : 조슈아  블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1)

 

반응형