다오의 개발일지

쓰레드의 상태와 제어 본문

JAVA

쓰레드의 상태와 제어

다오__ 2023. 6. 2. 21:08

쓰레드의 상태

 

 

 

 

 

 

sleep() 메서드

현재 쓰레드를 지정된 시간동안 멈추게 한다.

sleep() 쓰레드는 자기자신에 대해서만 멈추게 있다.

 

 

interrupt()메서드

이릿정지 상태인 쓰레드를 실행 대기상태로 만든다.

 

아래 코드를 보면 Thread.sleep메서드로 인해 1초동안 sleep상태가 되도록 설정되어있지만

Thread 실행하자마자 interrupt 걸어 runnable상태로 것을 있다.

 

 

join()

정해진 시간동안 지정한 쓰레드가 작업하는 것을 기다린다.

시간을 지정하지 않았을 때는 지정한 쓰레드의 작업이 끝날때까지 기다린다.

 

사용방법

Thread thread = new Thread(task, "thread");

Thread.start();

try{

Thread.join();

}catch (InterruptedException e){

e.printStackTrace();

}

 

코드는 메인쓰레드가 thread 작업을 마칠 때까지 기다린다.

 

  • Join또한 interrupt() 만나면 기다리는 것을 멈추기 때문에 InterruptedException 발생할 있다.

 

yield()

남은 시간을 다음 쓰레드에게 양보하고 쓰레드 자신은 실행대기 상태가 된다.

 

 

synchronized

쓰레드가 진행중인 작업을 다른 쓰레드가 침범하지 못하도록 막는것을 쓰레드 동기화(synchronization)이라고 한다.

 

동기화를 하려면 다른 쓰레드의 침범을 막아야 하는 코드들을 '임계영역'으로 설정한다.

 

임계영역에는 Lock 가진 하나의 쓰레드만 사용 가능하다.

 

 

wait(), notify()

침범을 막은 코드를 수행하다가 작업을 이상 진해앟ㄹ 상황이 아니면, wiat() 호출하여 쓰레드가 Lock 반납하고 기다리게 있다.

  • 그러면 다른 쓰레드가 락을 얻어 해당 객체에 대한 작업을 수행 있게 되고,
  • 추후에 작업을 진행할 상황이 되면 notify() 호출하여
  • 작업을 중단했던 쓰레드가 다시 Lock 얻어 진행할 있게 된다.

 

  1. wait()

실행중이던 쓰레드는 해당 객체의 waiting pool에서 notify() 기다린다.

  1. notify()

Waiting pool 있는 모든 쓰레드 에서 임의의 쓰레드만 통지를 받는다.

 

Lock, Condition

  1. Lock

Synchronized 블럭으로 동기화하면 자동적으로 lock이 걸리고 풀리지만,  같은 메서드 내에서만 lock을 있다는 제약이 있다.

이런 제약을 해결하기 위해 Lock클래스를 사용한다

 

ReentrantLock

재진입이 가능한 Lock, 가장 일반적인 배타 Lock

특정 조건에서 Lock을 풀고, 나중에 다시 Lock을 얻어 임계영역으로 진입이 가능하다.

 

Public class MyClass {

Private Object lock1 = new Object();

Private Object lock2 = new Object();



Public void methodA(){

Synchronized (lock1) {

methodB();

}

}

Public void methodB(){

Synchronized (lock2) {

//do something

methodA();

}

}

 

ReentrantReadWriteLock

  • 읽기를 위한 Lock과 쓰기를 위한 Lock을 따로 공유
  • 읽기에는 공유적, 쓰기에는 베타적인 Lock
  • Read-onlyLock이라고도 불린다.

StampedLock

  • ReentarantReadWriteLock에 낙관적인 Lock의 가능을 추가했다.
  • 낙관적인 Lock : 데이터를 변경하기 전에 락을 걸지 않는 것을 말한다. 낙관적인 락은 데이터 변경을 충돌이 일어날 가능성이 적은

상황에서 사용한다.