스레드 스케줄링
# 스레드 스케줄링에는 크게 선점형과 협력형 두 가지가 있다.
선점형 스레드 스케줄러
- 선점형 스레드 스케줄러는 스레드에게 공평하게 분배된 CPU 시간이 소진되었을 때, 스레드를 중지시키고 다른 스레드에게 CPU 제어권을 넘겨주는 일을 결정한다.
협력형 스레드 스케줄러
- 협력형 스레드 스케줄러는 CPU 제어권을 다른 스레드에게 넘겨주기 전에 실행 중인 스레드가 스스로 실행을 중단 할때 까지 기다린다.
- 협력형은 기아현상이 일어 날 수 있다. 모든 자바 가상머신은 우선순위에 따른 선점형 스레드 스케줄링 방식의 사용이보장된다.(선점형 스레드는 우선순위가 높은 스레드를 먼저 실행시키는 등의 문제로 인해 다른 스레드들은 기아현상에빠질 수도 있다. 잘 사용해야 한다.)
-> 우선순위가 높은 스레드들만 계속 실행되고 하단에 우선순위가 낮은 스레드들은 실행이 되지 않는 기아현상이 발생 할 수 있다.
쓰레드가 다른 스레드 실행을 위해 실행을 중지하거나 실행을 중지할 준비가 됐음을 알려 주는 방법
- I/O 블록
- 동기화된 객체에 의한 블록
- 명시적인 양보
- 슬립(sleep) 상태
- 다른 스레드 종료
- 객체 대기(wait)
- 스레드 종료(finish)
- 높은 우선순위 스레드에 의한 선점
- 스레드 일시 정지(suspend)
- 스레드 멈춤(stop)
- 블로킹
-> 블로킹은 스레드가 어떤 리소스를 얻기 위해 멈추고 기다려야 하는 상황에 발생하거나 어떠한 리소스에 의해서 블로킹되는 경우가 발생한다.
- 양보
-> yield를 명시적으로 하여 CPU 제어를 포기할 수 있다. 이 메소드는 가상 머신이 준비된 다른 스레드를 실행할 수 있도록신호를 보낸다.
-> 주의 할 점은 양보를 한다고 해서 락을 해제하는 것이 아니기에, 동기화를 사용하고 있는 곳에서는 yield를 사용하게 되면 다시 그 동기화된 자원을 해제해주는 별도의 작업을 거쳐야 하므로 그 의미가 반감된다.
- Sleep
-> sleep는 양보의 보다 강력한 형태이다. 양보는 단지 스레드가 스스로 실행을 중지 하고 같은 우선순위의 다른 스레드에게제어를 넘겨줄 의시랄 표현하는 것이지만, 슬립은 제어를 넘겨줄 다른 스레드의 존재 유무에 상관없이 호출한 스레드가 중지된다. 그러나 양보, 슬립 모두 기존의 락을 반환하는 과정은 존재 하지 않는다.
-> sleep 상태인 스레드를 명시적으로 interrupt()를 사용하여 깨울 수 있다.
- 스레드 조인
-> 자바는 다른 스레드의 종료를 대기할 수 있는 다음과 같은 세가지 join() 메소드를 제공한다.
//조인(join)된 스레드의 종료를 막연하게 기다린다.
public final void join() throws InterruptedException
// 스레드를 지정된 시간에 맞게 기다리며 그 시간 이후 다음 코드를 계속해서 진행한다.
Public final void join(long milliseconds) throws InterruptedException
Public final void join(long milliseconds, int nonoseconds) throws InterruptedException
Example)
Double[] array = new double[100];
For (int I =0; I < array.length; i++)
Array[i] = Math.random();
sortThread t = new SortThread(arrya);
t.start();
Try {
t.join(); //join된 sortThread 스레드가 종료될 때 까지 막연하게 기다린다.
System.out.println("Minimum : " + array[0]);
} catch(InterruptedException ex){}
Join은 현재 조인된 항목을 기다린다.
-> join은 future와 caller를 사용하여 구현하면 더 간단하고 편하기 때문에 잘 사용되지 않는다.
- 객체대기
-> 스레드는 객체를 기다리는 동안 객체의 락을 해제하고 객체를 사용 중인 다른 스레드에 의해 알림을 받
을 때까지 실행이 중지된다.
Ex) MenifestFile m = new ManifestFile();
JarThread t = new JarThread(m, in);
Synchronized(m) {
T.start();
Try {
M.wait();
Catch (InterruptedException ex) {
//예외 처리.
}
}
-> 대기중인 스레드는 대기 중인 객체의 락을 되찾으려고 시도하고, 락 획득에 성공할 경우, 스레드는 wait() 구문 바로다음부터 실행을 재기한다.
-> wait된 manifest 객체에 notifiy()를 던지면 다시 살아나서 동작을 진행한다.
MenifestFile themanifest;
InputStream in;
Public JarThread(Menifest m, InputStream in) {
theMenifest = m;
This.in = in;
}
@Override
Public void run() {
Synchronized (themenifest) {
Themenifest.notify();
}
}
->만약 리스트로 관리되는 여러 스레드의 어떤 스레드를 notify해줄지 모를경우 notifyall을 해주면 모두 해제 되지만, 해제된 스레드들이 동일 자원을 접근하려 할때 결국 하나의 스레드를 제외한 나머지 스레드들은 다시 wait 상태가된다.
6. 우선순위
- 자바에서 가장 높은 우선순위는 10이고, 가장 낮은 우선순위는 0이다. 기본 우선순위 값은 5이며 특별히 우선순위 값을지정하지 않으면 기본값으로 지정된다.
- Thread t = new Thread(츄);
- t.setPriority(8);//우선 순위 지정
- t.start();
'JAVA > Thread' 카테고리의 다른 글
Thread 크리티컬 세션 (0) | 2016.12.21 |
---|---|
java thread pool 소개 (0) | 2016.12.21 |
Thread 동기화 문제 (0) | 2016.12.21 |
JAVA Thread Futher, Callable, Executor (0) | 2016.12.21 |
Thread 폴링 방식 (0) | 2016.12.21 |