jad -o -r -sjava -8 -dtest target/**/*.class


-o : 덮어쓰기

-r : 해당 패키지 형태로 디렉토리 구조를 만듬(restore package directory structure)
-s java : 디컴파일된 파일의 확장자를 java로 생성

-8 : 유니코드 스트링을 ANSI 스트링으로 변환, (주로 유니코드 -> 한글)


-d : 디컴파일될 디렉토리(-d <dir> - directory for output files)


마지막은 디컴파일 해야할 타겟 지정 (target/**/*.class -> target 폴더 하위에 존재하는 class파일을 대상으로)

'Java' 카테고리의 다른 글

ConcurrentModificationException  (0) 2012.11.08
Serializable, 직렬화 (2)  (0) 2012.08.30
Serializable, 직렬화 (1)  (0) 2012.08.30

이름 목록에서 "hero"를 삭제하려고 하면 ConcurrentModificationException이 발생한다.

리스트를 순회하는 동안 요소를 추가, 삭제, 수정하면 안되기 때문이다.


그래서 Iterator를 사용한다.


그럼 정상적으로 해당 요소는 삭제된다. 이건 싱글 스레드에선 문제가 없어보인다.


근데 Iterator로 순회하는 도중에 다른 스레드에서 List에 접근하여 조작하려 한다면 어떻게 될까..

iterator는 HashTable이건 List건 부모의 내용이 바뀌지 않는 것을 전제로 사용된다 하기 때문에 분명 똑같은 예외가 발생할 것 같다.


방법은 원본 List는 순회하지 않으면 된다.

clone을 사용하여 복제된 List를 순회시키고 해당 조건문에서는 원본 List의 요소를 삭제하면 아무런 문제가 없어보인다.

물론, 더 좋은 방법이 있을지도 모르겠지만! 나중에 한번 더 고민해보지 뭐.. ;p



구글링 하다가 본 내용인데.. 죄다 영어라 이해하기 힘들다.. 아무튼 CopyOnWriteArrayList를 사용하면 위 문제는 해결된다.

하지만 애초에 우린 CopyOnWriteArrayList 보단 ArrayList를 많이 사용하기 때문에 특별한 경우가 아닌 이상에야 un-safe한 리스트를 사용할 이유가 없다고 생각한다.


암튼, 영어가 익숙해지면 한번 쭉- 읽어봅시다.. ( http://www.javacodegeeks.com/2011/05/avoid-concurrentmodificationexception.html )


CopyOnWriteArrayList 클래스는 동기화된 List 클래스보다 병렬성을 훨씬 높이고자 만들어졌다. 병렬성이 향상됐고, 특히 List에 들어있는 값을 Iterator로 불러다 사용하려 할 때 List 전체에 락을 걸거나 List를 복제할 필요가 없다.

( CopyOnWriteArrayList 와 비슷하게 Set인터페이스를 구현하는 CopyOnWriteArraySet 도 있다. )


'변경할 때마다 복사'하는 컬렉션 클래스는 불변 객체를 외부에 공개하면 여러 스레드가 동시에 사용하려는 환경에서도 별다른 동기화 작업이 필요 없다는 개념을 바탕으로 스레드 안전성을 확보하고 있다. 하지만 컬렉션이라면 항상 내용이 바뀌어야 하기 때문에, 컬렉션의 내용이 변경될 때마다 복사본을 새로 만들어 내는 전략을 취한다. 만약 CopyOnWriteArrayList에서 Iterator를 뽑아내 사용한다면 Iterator를 뽑아내는 시점의 컬렉션 데이터를 기준으로 반복하며, 반복하는 동안 컬렉션에 추가되거나 삭제되는 내용은 반복문과 상관 없는 복사본을 대상으로 반영하기 때문에 동시 사용성에 문제가 없다.


반복문에서 락을 걸어야 할 필요가 있기는 하지만, 반복할 대상 전체를 한번에 거는 대신 개별 항목마다 가시성을 확보하려는 목적으로 잠깐씩 락을 거는 정도면 충분하다.


변경할 때마다 복사하는 컬렉션에서 뽑아낸 Iterator를 사용할 때는 ConcurrentModificationException이 발생하지 않으며, 컬렉션에 어떤 변경 작업을 가한다 해도 Iterator를 뽑아내던 그 시점에 컬렉션에 들어 있던 데이터를 정확하게 활용할 수 있다.


물론 컬렉션의 데이터가 변경될 때마다 복사본을 만들어내기 때문에 성능의 측면에서 손해를 볼 수 있고, 특히나 컬렉션에 많은 양의 자료가 들어 있다면 손실이 클 수 있다. 따라서 변경할 때마다 복사하는 컬렉션은 변경 작업보다 반복문으로 읽어내는 일이 훨씬 빈번한 경우에 효과적이다.


'Java' 카테고리의 다른 글

decompile..  (0) 2015.11.10
Serializable, 직렬화 (2)  (0) 2012.08.30
Serializable, 직렬화 (1)  (0) 2012.08.30

이번엔 다른 예제로 writeReplace와 readResolver를 사용해보자..

얕은 지식으론 설명에 한계가 있기 때문에 그냥 이럴때 이렇게 사용한다더라.. 정도의 상황 설명이....


다음과 같은 Json객체를 직렬화 하려고 한다. 물론 설명을 위해 억지로 만들어진 객체이다 - -;;


앞서 Person객체를 직렬화 했던 방법과 동일하다. 그러나.......


테스트는 통과하지 못하고..

Json객체가 필드로 가지고 있는 JsonObject객체를 직렬화 할수 없다는 예외가 발생한다.

JsonObject객체는 Serializable를 구현하지 않은 객체라서 직렬화 할수 없었다.


물론 필드를 직렬화에 포함시키지 않는 방법이 있다.

 * 참고 - private transient JsonObject jso;


암튼, 미션은 JsonObject도 함께 직렬화를 해야한다는 것인데.. (수석님이 여러가지 꼼수들을 보여주셨지만 그건 패스하고...- -;;)

writeReplace와 readResolve를 사용해서 해결한다.


writeReplace 할때 Proxy객체를 하나 정의해서 jsonString을 잠시 보관하고 Proxy객체를 리턴한다.

그리고 읽어올땐 Proxy객체에 정의된 readResolve를 통해 다시 Json객체를 생성해서 리턴한다.

둘다 리턴되는 값은 Serializable를 구현한 객체만 가능하다.


상당히 간단한 예제였기 때문에 쉬워보일수도 있는데 좀 덩치큰 객체들이 직렬화 될때를 상상해보면 저런 후킹 메서드들을 어떻게 잘 사용할수 있을지 걱정이 된다......

'Java' 카테고리의 다른 글

decompile..  (0) 2015.11.10
ConcurrentModificationException  (0) 2012.11.08
Serializable, 직렬화 (1)  (0) 2012.08.30

우리 수석님께서 예제를 주시며 직렬화 해보라는 미션과 직렬화에 대한 질문을 하셨다......T^T


사실 직렬화를 해본적이 없어서 설명하기가 상당히 난해했다.

교육기관이나 책같은걸 보면 객체 자체를 파일에 쓰고.. 다시 역직렬화해서 읽어오는 예제가 많다.


그래서 직렬화라는게 그게 다인줄 알았다...- -;


사실 난 모르는게 너무 많고 어설픈 개발일을 하고 있다보니 이런 고급 기술을 쓸 기회가 없어서 나중에 진짜 개발자가 되었을때 써먹기 위해 포스팅 해본다..


이런 Person 클래스가 있고, 


이것을 직렬화 하려면 이런식으로 한다.


보통 예제들은 파일에 쓰고 다시 파일을 읽어다가 객체로 만드는데 여기선 그냥 잠깐 Byte배열로 저장했다가 다시 그 바이트를 읽어다가 객체로 만들었다.

암튼, 이게 일반적으로 알고있는 직렬화 라는거였다. (이건 나도 해봤어!)

물론, TestCase도 통과했다.


다음으로 Person객체에 몇가지 메서드를 정의해본다.


다시 테스트 실행을 해보면,

두둥!! 방금 Person객체에 정의한 메서드들이 위와 같은 순서로 실행됬다. 물론 테스트는 실패했을꺼다~

정확한 설명은 어렵지만 직렬화를 할때 JVM이 저런 메서드를 잡아서(?) 실행하는것 같다.......

후킹 메서드라 해야할까.. (용어 지식도 딸림....)


아무튼 이중에 writeObjectreadObject를 사용해서 테스트를 통과시키려면... 자알~ 구현을 해야한다..


이런식으로 구현할수 있고, 사실 위 예제는 불필요하게 구현을 하지 않아도 되잖아?!

좀 더 복잡한 객체, 혹은 어떠한 제약조건이 있을시에 언젠가 분명 사용할 날이 올것이다.


다음편....

'Java' 카테고리의 다른 글

decompile..  (0) 2015.11.10
ConcurrentModificationException  (0) 2012.11.08
Serializable, 직렬화 (2)  (0) 2012.08.30

+ Recent posts