TA

java.util.ConcurrentModificationException 해결방법

우진2015 2017. 1. 24. 14:51

일반적인 Web application에서는 단일 thread에 의해 공유자원이 사용 됨으로 잘 발생하지 않습니다. 그러나 Client가 동시에 여러개의 Request를 요청할 때 발생 할 가능성이 있습니다. 물론 서버의 성능이 좋다면 발생하는 가능성이 줄어들기는 하지만, 근본적으로 Application 개발시 Session사용의 부주의로 인해서 발생한다고 생각합니다.


Client에서 동시에 여러개의 Request를 서버로 보내면, 서버는 각각의 Thread가 Request에 대한 업무를 처리합니다.

이 Exception은 동시에 여러개의 Thread가 단일 Session 정보를 공유하고, 갱신하기에 발생하는 문제입니다.


JEUS의 경우 로그에서 “jeus.sessionmanager.util.SerializationException: failed to serialize a attribute” 를 볼 수 있는데, 이로 인해서 문제해결이 session의 자체의 문제로 생각 할 수 있었을 것으로 보입니다.


하지만,  Session의 정보를 여러 thread가 동시에 수정하다 보니 내용의 무결성이 회손되고, 그로 인해 이와 같이 exception이 발생한 것으로 보입니다.


따라서 다중 Thread가 단일 Session정보를 공유 할때는 공유자원에 대한 동기화 작업이 필요합니다.


또는 session에 저장하는 객체를 Thread safe 한 concurrentHashMap 을 사용하는 방법도 있습니다.


무엇보다 웹 어플리케이션에서는 어플리케이션을 개발 할때는 Thread safe 한지 반드시 고려해서 작업이 진행 되어야 합니다.


만약 Application 개발 구조 자체가 너무 많은 정보를 Session에 담아서 사용하고 있으며, 성능에 대한 이슈로 인해서  동기화도 불가하다면, Session에 있는 IO 정보를 별도 메모리에 카피하여 진행하고, 완료시 Session 값을 업데이트 하는 방식으로 Session 사용 부분을 최소화 하여 문제를 처리 할 수있습니다.


<<처리방법>>

1. Session에 저장 객체 동기화(Synchronized) ==> Thread safe

2. concurrentHashMap 사용 ==> Thread Safe

3. 내부 business layer까지 같은 객체 주소 사용 할 경우, 객체 복사 후 업무처리로 Session 의존성 최소화 ==> Thread safe + Deep copy


복잡한 구조의 객체를 사용 할 경우에는 Deep Copy를 활용하여 객체를 복사 할 수 있습니다.