쓰레드

soob·2021년 3월 23일
0

생존 java

목록 보기
6/6

1.스케줄링을 위한 함수 정리

  • static void sleep
  • void join : 다른 쓰레드를 실행 시키는 함수
  • void interrupt
    • sleep이나 join에 의해 일시정지상태인 쓰레드를 깨워서 실행대기상태로 만든다. 해당 쓰레드에서는 InterruptedException이 발생함으러써 일시정지상태를 벗어나게 된다.
    • 진행 중인 쓰레드의 작업이 끝나기 전에 취소시킨다. 단지 멈추라고 요청만 하는 것일 뿐 쓰레드를 강제로 종료시키기즌 못한다. 그저 쓰레드의 interrupted 변수를 false에서 true로 변경 할 뿐이다.
    • InterruptedException이 발생하면, 쓰레드의 interrupted 상태는 false로 자동 초기화 된다.
  • static void yield
    • 실행 중에 자신에게 주어진 실행시간을 다른 쓰레드에게 양보하고 자신은 실행대기상태가 된다.

2. 동기화 (공유자원 관리 : 다수의 스레드가 공유 자원 혹은 공유 데이터에 동시에 접근할 때 서로 순서대로 충돌 없이 배타적으로 접근하기 위해)

2.1 synchronized를 이용한 동기화

  • 메서드 전체를 임계영역으로 지정
    public synchronized void func(){}

  • 특정한 영역을 임계 영역으로 지정
    synchronized(변수){
    }

  • 메서드 전체를 임계역역으로 하기 보단, 블락을 잘 이용해 임계역역을 최소화 하는 것이 더 효율적이다.

2.2 wait()와 notify(), notifyAll()

  • 동기화 하는 것은 좋은데, 특정 쓰레드가 객체의 락을 가진 상태로 오랜시간을 보내지 않도록 하는것도 중요하다.
  • 코드를 수행하다 작업을 더 이상 진행할 상황이 아니면, 일단 wait()을 호출하여 쓰레드가 락을 반납하고 기다리게 한다.
  • 매개변수가 있는 wait은 지정된 시간동안만 기다린다.
  • wait이 호출되면 해닥 객체의 waiting pool에서 기다린다.
  • 나중에 작업을 진행할 수 있는 상황이 되면 notify()를 호출해서, 다시 락을 얻어 작업을 진행하게 한다.
  • notifyAll()이 호출되면, 해당 객체의 waiting pool에 대기중인 모든 쓰레드를 깨운다. (기아 현상을 막을 수 있다)
  • wait와 notify를 이용해서는 선별적으로 lock을 줄 수 있다.

2.3 Lock과 Condition을 이용한 동기화

  • 자동적으로 lock의 잠금과 해제가 돤리되는 synchronized블럭과 달리, lock클래스들은 수동으로 lock을 잠그고 해제해야 한다.
lock.lock()
try{
	//임개영역
} finally {
	lock.unlock();
}
  • Condition을 이용해서 락을 주고 받고 한다.
    • await()
    • signal()
    • signalAll()

private ReentrantLock lock = new ReentrantLock();
private Condition forCook = lock.newCondition();
private Condition forCust = lock.newCondition();

lock.lock();
try{
	try{
    	forCook.await(); // COOK 쓰레드를 기다리게 한다
    } catch(InterruptedExceprion e){}
    
    forCust.signal(); // notifiy; 기다리고 있는 CUST를 깨운다.
} finally{
	lock.unlock();
}
profile
쓸데없는 소리를 좋아하는 개발자

0개의 댓글