본문 바로가기

개발이야기/open source

[Hazelcast]Java concurrent lock 구현하기

Hazelcast Lock

하젤케스트에서 사용하는 ILock은  java.util.concurrent.locks.Lock 의 상속구현체이다. 즉, 모든 클러스터에서 네트워크상에 이상이 없는한, lock이 잡힌 critical section은 한번에 한 쓰레드만 도는 것이 보증된다. Lock 구현은 매우 신경써서 하지 않으면 문제점이 바로 생겨날 가능성이 있으므로 주의하여 구현해야만 한다. 

 

Try-catch구문을 사용하여 Lock 사용하기

lock안쪽 구문은 반드시 try-catch 구문을 사용해야한다. 만약 critical section에서 에러가 났을때 unlock 가능하도록 도와주기 때문이다. 또한 lock구문에서 에러났을때 unlock되는 것을 막기 위해 lock method의 밖에도 try-catch를 사용해야한다.

import com.hazelcast.core.Hazelcast;
import java.util.concurrent.locks.Lock;

HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
Lock lock = hazelcastInstance.getLock( "myLock" );

try{
    lock.lock();
    try {
      // do something here
    } finally {
      lock.unlock();
    }
}catch(Exception e){
    //when lock occurs error
}
 

tryLock timeout 구문을 사용하여 lock을 release하기

만약 어떤 클러스터가 lock을 계속해서 잡고 있으면 다른 thread는 영원히 lock을 기다리게 된다. 이것을 방지하기 위해,  tryLock과 timeout value를 사용하여 이를 방지할 수 있다. 

아래 코드는 10초동안 critical section에 들어가기 위해 기다리다가 10초안쪽으로 section에 진입하지 못하면 else 구문으로 분기를 타게 된다.

if ( lock.tryLock ( 10, TimeUnit.SECONDS ) ) {
  try {  
    // do some stuff here..  
  } finally {  
    lock.unlock();  
  }   
} else {
  // warning
}

 

Lease time을 사용하여 lock 잡고 있는 시간 제한하기

critical section에 대해서 lease time(대여 시간) 을 부여해서 lock이 시간이 지나면 자동으로 풀리도록 구현도 가능하다. 그러나 만약 lease time(대여시간)이 지나서(time expires) unlock된다면 자동으로 IllegalMonitorStateException이 발생하게 되며, 이는 critical section이 침범(broken)된 것으로 보면 된다.

lock.lock( 5, TimeUnit.SECONDS )
try {
  // do some stuff here..
} finally {
  try {
    lock.unlock();
  } catch ( IllegalMonitorStateException ex ){
    // WARNING Critical section guarantee can be broken
  }
}

 

End of Document