ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] 컬렉션 프레임워크 - 동기화, 병렬 처리
    CSE/Java 2015. 9. 20. 09:08


    컬렉션 프레임 워크는 여러 절로 구성되어 있습니다.



    Intro

    List 컬렉션

    Set 컬렉션

    Map 컬렉션

    검색 기능을 강화시킨 컬렉션

    LIFO와 FIFO 컬렉션

    동기화 & 병렬처리를 위한 컬렉션





    동기화된 컬렉션

     컬렉션 프레임워크의 대부분의 클래스들은 싱글 스레드 환경에서 사용할 수 있도록 설계되었습니다.


     그렇기 때문에 여러 스레드가 동시에 컬렉션에 접근한다면 의도하지 않게 요소가 변경될 수 있는 불안전한 상태가 됩니다.


     Vector와 Hashtable은 동기화된(synchronized) 메소드로 구성되어 있기 때문에 멀티 스레드 환경에서 안전하게 요소를 처리할 수 있지만, ArrayList, HashSet, HashMap은 동기화된 메소드로 구성되어 있지 않아 멀티 스레드 환경에서 안전하지 않습니다.



     경우에 따라서는 ArrayList, HashSet, HashMap을 싱글 스레드 환경에서 사용하다가 멀티 스레드 환경으로 전달할 필요도 있을 것입니다.


     이런 경우를 대비해서 컬렉션 프레임워크는 비동기화된 메소드를 동기화된 메소드로 래핑(Wrapping)하는 Collections의 synchronizedXXX() 메소드를 제공하고 있습니다.


     파라미터로 비동기화된 컬렉션을 대입하면 동기화된 컬렉션을 리턴합니다.










     다음 코드는 ArrayList를 Collections.synchronizedList() 메소드를 사용해서 동기화된 List로 변환합니다.










     다음 코드는 HashSet을 Collections.synchronizedSet() 메소드를 사용해서 동기화된 Set으로 변환합니다.










     다음 코드는 HashMap을 Collections.synchronizedMap() 메소드를 사용해서 동기화된 Map으로 변환합니다.
















    병렬 처리를 위한 컬렉션

     동기화된 컬렉션은 멀티 스레드 환경에서 하나의 스레드가 요소를 안전하게 처리하도록 도와주지만, 전체 요소를 빠르게 처리하지는 못합니다.


     하나의 스레드가 요소를 처리할 때 전체 잠금이 발생하여 다른 스레드는 대기 상태가 됩니다.


     그렇기 때문에 멀티 스레드가 병렬적으로 컬렉션의 요소들을 처리할 수 없습니다.


     자바는 멀티 스레드가 컬렉션의 요소를 병렬적으로 처리할 수 있도록 특별한 컬렉션을 제공하고 있습니다.


     java.util.concurrent 패키지의 ConcurrentHashMap과 ConcurrentLinkedQueue 입니다.


     ConcurrentHashMap은 Map 구현 클래스이고, ConcurrentLinkedQueue는 Queue 구현 클래스입니다.



     ConcurrentHashMap을 사용하면 스레드에 안전하면서도 멀티 스레드가 요소를 병렬적으로 처리할 수 있습니다.


     이것이 가능한 이유는 ConcurrentHashMap은 부분(segment) 잠금을 사용하기 때문입니다.


     컬렉션에 10개의 요소가 저장되어 있을 경우, 1개를 처리할 동안 전체 10개의 요소를 다른 스레드가 처리하지 못하도록 하는 것이 전체 잠금이면, 처리하는 요소가 포함된 부분만 잠금하고 나머지 부분은 다른 스레드가 변경할 수 있도록 하는 것이 부분 잠금입니다.


     다음은 ConcurrentHashMap 객체를 생성하는 코드 입니다. 사용하는 방법은 다른 Map 구현 객체와 마찬가지로 Map 인터페이스의 메소드를 호출하면 됩니다.


















     ConcurrentLinkedQueue 는 락-프리(Lock-Free) 알고리즘을 구현한 컬렉션입니다.


     락-프리 알고리즘은 여러 개의 스레드가 동시에 접근할 경우, 잠그을 사용하지 않고도 최소한 하나의 스레드가 안전하게 요소를 저장하거나 얻도록 해줍니다.


     다음은 ConcurrentLinkedQueue 를 생성하는 코드입니다.












     사용하는 방법은 다른 Queue 구현 객체와 마찬가지로 Queue 인터페이스의 메소드를 호출하면 됩니다.









     * 이 포스트은 서적 '이것이 자바다' 를 참고하여 작성한 포스트입니다.



    댓글

Designed by Tistory.