안녕하세요 알통몬입니다. 공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^
|
컬렉션 프레임워크에는 LIFO 자료 구조를 제공하는 Stack 클래스와
FIFO 자료 구조를 제공하는 Queue 인터페이스를 제공합니다.
아래 그림은 LIFO 구조와 FIFO 구조를 설명한 사진입니다.
JVM 스택 메모리가 Stack을 응용한 대표적인 예입니다.
Stack 메모리에 저장된 변수는 나중에 저장된 것부터 제거됩니다.
쓰레드 풀이 작업 큐는 Queue를 응용한 예입니다.
Stack 클래스의 주요 메소드
생성 방법
: Stack<E> stack = new Stack<E>();
예제)
예제를 실행해보면 저장된 순서의 반대로 출력됩니다.
Queue의 주요 메소드
Queue 인터페이스를 구현한 클래스는 LinkedList인데요.
LinkedList는 List 인터페이스를 구현했으므로 List 컬렉션이기도 합니다.
생성 방법
: Queue<E> linkedList = new LinkedList<E>();
예제)
동기화 컬렉션
컬렉션 프레임워크의 대부분의 클래스들은
싱글 스레드 환경에서 사용할 수 있도록 설계되었습니다.
여러 스레드가 동시에 컬렉션에 접근한다면
요소가 변경될 수 있는 불안전한 상태가 됩니다.
Vector 와 Hashtable은 동기화된 메소드로 구성되어 있어서 멀티 스레드 환경에서
안전하게 요소를 처리할 수 있지만,
ArrayList,HashSet, HashMap은 동기화된 메고드로 구성되어 있지 않아
멀티 스레드 환경에서 안전하지 않습니다.
경우에 따라 ArrayList,HashSet, HashMap을 싱글 스레드 환경에서
사용하다가 멀티 스레드 환경으루 전달할 필요도 있을 수 있습니다.
이런 경우에 대비해 컬렉션 프레임워크는 비동기화된 메소드로
래핑하는 Collections 의 synchronizedXXX()를 제공하고 있습니다.
매개값으로 비동기화된 컬렉션을 대입하면 동기화된 컬렉션을 리턴합니다.
List<T> list = Collections.synchronizedList(new ArrayList<T>());
Set<E> set = Collections.synchronizedSet(new HashSet<E>());
Map<K, V> map = Collections.synchronizedMap(new HashMap<K,V>());
병렬 처리를 위한 컬렉션
동기화된 컬렉션은 멀티 스레드 환경에서
하나의 스레드가 요소를 안전하게 처리하도록 도와주지만,
전체 요소를 빠르게 처리하지는 못합니다.
하나의 스레드가 요소를 처리할 때 전체 잠금이 발생하여 다른 스레드는 대기 상태가 됩니다.
그렇기에 멀티 스레드가 병렬적으로 컬렉션의 요소들을 처리할 수 없습니다.
멀티 스레드가 컬렉션의 요소를 병렬적으로 처리할 수 있도록 특별한 컬렉션을 제공합니다.
java.util.concurrent 패키지의 ConcurrentHashMap 과 ConcurrentLinkedQueue입니다.
ConcurrentHashMap은 Map 구현 클래스이고, ConcurrentLinkedQueue은 Queue 구현 클래스입니다.
ConcurrentHashMap을 사용하면 스레드가 안전하면서도
멀티 스레드가 요소를 병렬적으로 처리할 수 있습니다.
이것이 가능한 이유는 ConcurrentHashMap은 부분 잠금을 사용하기 때문입니다.
컬렉션에 10개의 요소가 저장되어 있는 경우 1개를 처리할 동안
10개의 요소를 다른 스레드가 처리하지 못하도록 하는 것이 전체 잠금이라면
처리하는 요소가 포함된 부분만 잠금하고 나머지 부분은 다른 스레드가
변경할 수 있도록 하는 것이 부분 잠금입니다.
생성 코드
Map<K,V> map = new ConcurrentHashMap<K,V>();
ConcurrentLinkedQueue는 락 프리 알고르즘을 구현한 컬렉션입니다.
락-프리 알고리즘은 여러 개의 스레드가 동시에 접근할 경우
잠금을 사용하지 않고도 최소한 하나의 스레드가 안전하게 요스를 저장하거나 얻도록 해줍니다.
생성 코드
Queue<E> queue = new ConcurrentLinkedQueue<E>();
사용 방법은 다른 Queue 구현 객체와 마찬가지로 Queue 인터페이스의 메서드를 호출하면 됩니다.
이상입니다.
'자바' 카테고리의 다른 글
자바 스트림 Java Stream => 스트림의 특징 (0) | 2017.03.30 |
---|---|
자바 스트림 Java Stream - 스트림이란?, 반복자 스트림 (0) | 2017.03.27 |
자바 컬렉션 Java - TreeMap, Comparable과 Comparator (0) | 2017.03.25 |
자바 컬렉션 Java 컬렉션 - 이진트리구조, TreeSet (0) | 2017.03.25 |
자바 Map 컬렉션 자바 셋 컬렉션 -> Map, HashMap, Hashtable, Properties (0) | 2017.03.24 |