AOP(Aspect Oriented Program)을 위해 Proxy를 이용하여 특정 클래스의 method하는 경우 InvocationHandler를 implements 한다. 이때 invoke() 메소드 내에서 synchronized 처리에 주의해야 한다. 다음 코드의 경우

public class DefaultInvocationHandler implements InvocationHandler {

Object monitor = new Object();

 

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

    {

      synchronized(monitor) {

        try {

          return method.invoke(targetObject, args);

        } catch (Throwable e) {

          e.printStackTrace(System.out);

          throw e;

        }

      }

    }

}


이 경우 일반적인 경우에는 잘 작동하지만 호출하는 메소드 내에서 다시 Proxy 객체의 메소드를 호출하는 경우 Handler 내부적으로는 recursive하게 call되어 두번째 메소드가 수행되는 시점에서는 monitor에 대한 lock을 가져오지 못해 무한대기 상황이 발생한다.
따라서 method.invoke(targetObject, args); 이부분 수행할 때에는 lock에 대한 처리가 없어야 한다.

크리에이티브 커먼즈 라이센스
Creative Commons License

Posted by 김형준


Trackback URL : http://www.jaso.co.kr/trackback/220

Comments List

  1. nokarma 2008/02/05 13:39 # M/D Reply Permalink

    synchronized는 reentrant lock을 거는걸로 알고 있는데 왜 recursive call이 되면 무한대기 상황이 발생하나요?

    1. 김형준 2008/02/05 14:36 # M/D Permalink

      님이 말씀하신대로 동일 thread에 대해서는 reentrant가 되네요... 제가 사용한 코드 상황을 보니 여러 Thread가 하나의 클래스에 있는 메소드를 호출하는데 이 클래스가 Proxy를 이용하여 생성된 클래스 입니다. 따라서 위와 같은 코드로 구성하면 원본 클래스에서는 동기화 작업을 잘 구성하였지만 InvocationHandler에 대해 동기화 처리를 하기 위해 lock을 걸 경우에는 조금 고려해서 걸어야 한다는 취지로 작성했습니다. *^^* 좋은 지적 감사합니다.

  2. nokarma 2008/02/05 14:46 # M/D Reply Permalink

    결국 무한대기와 Proxy based AOP InvocatioHandler는 무관하다는 얘기인가요?

    1. 김형준 2008/02/05 14:56 # M/D Permalink

      예... Proxy로 인해서 생기는 문제가 아니라 Proxy를 사용하기 때문에 눈에 잘 띄지 않아서 지나치기 쉬운 부분입니다. 저도 혹시나 해서 테스트 코드를 몇개 만들어서 해보니까 동일 Thread에 대해서는 lock 상황이 발생하지 않네요...

Leave a comment
« Previous : 1 : ... 227 : 228 : 229 : 230 : 231 : 232 : 233 : 234 : 235 : ... 410 : Next »