// 방법 1 : 메서드 전체를 임계영역으로 설정
public **synchronized** void useBuy(int price){}
// 방법 2 : 특정 영역을 임계영역으로 설정
public void useBuy(int price){
**synchronized ( 락을 걸고자 하는 객체의 참조변수 ) {**
**}**
}
임계영역설정은 멀티쓰레드 프로그램의 성능을 좌우하기 때문에
가능하면 메서드 전체에 락을 거는 방식보다 synchronized 블록을 통해 임계영역을 최소화 해
효율적인 프로그램이 되도록 노력해야한다.
- 특정 쓰레드가 객체의 락을 가진 상태로 오랜시간을 보내지 않도록 해야한다.
- 이 경우 lock 이 반납 될 때까지 다른 쓰레드들은 작업이 원활이 진행되지 않는다.
- wait(), notify(), notifyAll() 을 통해 조절
- Object 에 정의되어있다.
- 동기화 블럭 내에서만 사용할 수 있다.
- 보다 효율적인 동기화를 가능케한다.
- 단 오래 기다린 쓰레드가 락을 얻는다는 보장은 없다.
- wait()
- 쓰레드가 lock 을 반납하고 기다리게 한다.
- 실행중이던 쓰레드는 해당 객체의 대기실(wating pool) 에서 통지를 기다린다.
- notify()
- 작업을 중단했던 쓰레드가 다시 락을 얻어 작업을 진행할 수 있도록 한다.
- 해당 객체의 대기실에 있던 모든 쓰레드 중에서 임의의 쓰레드만 통지를 받는다.
- notifyAll()
- 기다리는 모든 쓰레드에게 통지한다.
- 그러나 lock 을 얻을 수 있는것은 하나의 쓰레드이므로
나머지 쓰레드는 통보를 받았지만 lock 을 얻지 못하여 다시 lock 을 기다리게 된다.
private ReentrantLock lock = new ReentrantLock();
// lock 으로 condition 을 생성
private Condition useConditionA = lock.newCondition();
private Condition useConditionB = lock.newCondition();
private Condition useConditionC = lock.newCondition();