스레드의 개수가 코어의 수보다 많을 경우, 스레드를 어떤 순서에 의해 실행할 것인가를 결정하는 것입니다.
스레드 스케줄러에 의해 여러 스레드들이 아주 짧은 시간동안 번갈아가면서 스레드의 run() 메소드를 조금씩 실행한다.
각 스레드가 우선순위를 갖고 있고, 우선순위가 높은 스레드부터 수행시키는 형식이다.
-> 개발자가 어떤 스레드를 우선적으로 처리할 지 우선순위를 부여할 수 있다.
thread.setPriority(1~10);
thread.setPriority(Thread.MIN_PRIORITY);
thread.setPriority(Thread.NORM_PRIORITY);
thread.setPriority(Thread.MAX_PRIORITY);
순환 할당방식은 시간 할당량을 정해서 하나의 스레드를 정해진 시간만큼 실행하고 다시 다른 스레드를 실행하는 방식입니다. -> 각 OS에 의해 정해진 Time slice만큼 할당하기 때문에 개발자가 임의로 수정할 수 없다.
JVM은 우선순위 방식의 선점형 스케줄링을 사용한다. 만약 스레드 간 서로 같은 우선순위를 가진다면, FIFO 방식으로 처리한다. 선점형 스케줄링이란 것은, 낮은 우선순위의 스레드가 Runnable로 먼저 대기하고 있더라도, 높은 우선순위의 스레드가 Runnable해지면, 낮은 우선순위의 스레드가 선점당하고, 높은 우선순위의 스레드가 실행되도록 스케줄링된다.
현재 구현한 스레드의 동작방식은 Round-Robin 방식으로 일정한 시간을 분할하여 스레드가 수행되는 식이다. 만약 우선순위로 구현해야 한다면, 어떻게 해야할 지 고민된다.
javascript에서 사용하는 타이머 중 하나인 setTimeout에 대해서 알아보자.
자바스크립트는 기본적으로 싱글 스레드로 동작한다. 그렇기 때문에 한 번에 한 동작밖에 할 수가 없다.
만약, setTimeout을 하고 어떤 동작을 하게되면, 이 동작은 콜스택에 올라가지 못하고 task queue에 올라가서 대기한다. 그리고 setTimeout이 끝나서 호출스택이 비면 그 다음 task queue에 있는 작업을 콜스택으로 올려 작업을 이어간다.
단순하게 생각해서 Thread의 sleep으로 1초를 주면 될 것 같았는데, 실제로는 1초의 sleep이후 로직이 실행되는 시간까지 고려하기 때문에 1초가 아니었다. 그럼 어떻게 해야 정확한 타이머를 구현할 수 있을까?
이번에 미션을 하면서 Timer 클래스를 사용했다. Timer 클래스는 TimerTask 객체를 받아서 일정 시간간격 별로 수행할 수 있는 함수를 제공하는데, 이 때 schedule을 이용해서, Interval을 1000ms로 놓고 동작시키면 정확도가 꽤 높은 타이머를 구현할 수 있다고 한다.
멀티 프로세스, 멀티 스레드에서 공유자원을 갖고 다투는 상황을 Race condition이라고 한다. 동시에 입출력과 read가 반복되는 과정에서 접근 순서에 따라 전혀 다른 결과를 초래할 수 있기 때문에 이러한 동기화 문제가 멀티 스레드에서는 매우 중요하다.
그래서 개발자들은 mutex, sepaphore 등의 기법을 이용하여 공유자원을 관리한다.