반응형
실행 어라운드 패턴(Execute around pattern)에 대한 두번째 예시 입니다.
먼저 1번글에서는 resource의 명시적인 해제시 해체할 수 있는 틀(try-catch-with-resource)를 만들어 넣고 내부에 인자로 실제 동작해야 할 구문을 넣는 형태를 얘기했었습니다.
이때 인자는 당연히 functional interface 입니다.
같은 방법으로 이번에는 lock을 사용하는 방법을 알아봅니다.
잠금(lock)의 관리
lock은 왜 써야 할까요?
저는 사실 synchronized만 쓴 터라 lock의 개념이 무척 궁금했더랍니다.
Java5부터 추가된 개념으로 동기화를 좀더 디테일?? 하게 관리하기 위해서 사용합니다.
예를 들면 하나의 함수 블럭을 넘어간다던가, 무작정 lock을 대기하는게 아니라 timeout을 건다든가..등등 세밀하게 조정할 수 있는거죠
lock의 내용이 궁금하시다면 잘 정리된 아래 블로그를 확인 하시면 됩니다.
lock을 사용하기 위해서는 명시적으로 lock과 unlock을 해야하고 따라서 try-catch를 써야만 안전합니다.
역시..
execute around pattern에 딱 맞는 조건이네요.
lock의 기본 동작 코드
일단 lock을 사용하기 위해서는 lock을 상속받아 구현하 ReentrantLock을 사용합니다.
public class Locking {
Lock lock = new ReentrantLock(); //or mock
protected void setLock(final Lock mock) {
lock = mock;
}
public void doOp1() {
lock.lock();
try {
//...critical code...
} finally {
lock.unlock();
}
}
//...
이건 doOp1() 함수에 lock을 걸고 푸는 코드가 다 들어있습니다.
요 기능만 같는 클래스로 분리해 보겠습니다.
public class Locker {
public static void runLocked(Lock lock, Runnable block) {
lock.lock();
try {
block.run();
} finally {
lock.unlock();
}
}
}
이렇게 runLocked란 함수를 이용하면 호출 부분에서는 lock과 unlock을 pair를 신경쓰지 않고 사용이 가능합니다.
public void doOp2() {
runLocked(lock, () -> {/*...critical code ... */});
}
public void doOp3() {
runLocked(lock, () -> {/*...critical code ... */});
}
public void doOp4() {
runLocked(lock, () -> {/*...critical code ... */});
}
반응형
'개발이야기 > Java' 카테고리의 다른 글
Java 8 Lambda를 이용한 lazy evaluation (0) | 2017.12.13 |
---|---|
Java 8 Lambda를 이용한 virtual proxy pattern (0) | 2017.12.12 |
Java 8 Lambda를 이용한 Execute around pattern #1 - resource 관리 (0) | 2017.12.05 |
Java의 동기화 Synchronized 개념 정리#2 (7) | 2017.11.20 |
Java의 동기화 Synchronized 개념 정리#1 (20) | 2017.11.19 |