Java의 모든 객체는 락을 가지고 있다. 이 때, Synchronized메서드를 실행하기 위해서는 락을 얻어야 하는데 다음 2가지 상황이 발생할 수 있다.
1 ) 락을 요청했지만 만약 이미 실행중인 p가 있는 경우
-> 다른 p는 대기해야 한다. (진입 집합)
2 ) sync에 있던 p가 특정 조건을 기다려야 하는 경우
-> 대기 집합
[Java 모니터를 이용한 생산자/소비자]
insert(E item) / E remove() 가 주요 함수
public synchronized void insert(E item) {
while (count == BUFFER_SIZE) { // 버퍼가 꽉 차 있으면
try {
wait(); 대기
} catch {
InterruptedException ie
}
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
count++;
notify();
}
}
public synchronized E remove() {
E item;
while (count == 0) { // 버퍼가 비어 있으면
try {
wait(); // 대기
} catch {
InterruptedException ie
}
item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;
notify();
return item;
}
}
[Java 재진입 락, 세마포]
<재진입 락>
ReentrantLock() / lock() / unlock()
Lock key = new ReentrantLock(); //
key.lock();
try {
/* 임계 구역 */
} finallly {
keyy.unlock();
}
<세마포>
sem.acquire() / sem.release();
Semaphore sem = new Semaphore();
try {
sem.acquire();
} finally {
sem.relesase();
}
<조건 변수>
public void doWork(int threadNumber) {
lock.lock();
try {
if(threadNumber != turn)
condVars[threadNumber].await();
///////////////////////////////////
///////////////////////////////////
///////////////////////////////////
turn = (turn + 1) % 5;
condVars[turn].signal();
} catch (InterruptedException ie) {
finally {
lock.unlock();
}
}