Java Thread Safe Collections - List, Queue, Set, Map
( 이미지 출처 : https://openjdk.java.net )
Thread safe 한 Collection(List, Queue, Set) 그리고 Map의 구현체 사용법에 대해서 기술합니다.
List
// JDK 1.2 이상에서 사용가능
List<String> list0 = Collections.synchronizedList(new LinkedList<>());
// JDK 1.5 이상에서 사용가능
List<String> list1 = new CopyOnWriteArrayList();
Collections.synchronizedList 와 CopyOnWriteArrayList를 비교해보면,
Collections.synchronizedList 는 list에 많은 데이터를 담을 때 유리하며 READ시 단일 쓰레드가 처리하기 때문에 느립니다.
위의 예제처럼 ArrayList만이 아니라 LinkedList 등 List의 다양한 구현체들의 특성을 활용할 수 있습니다.
CopyOnWriteArrayList는 쓰기 동작에서만 lock을 사용하고 읽기 동작은 lock 없이 사용 가능하다. 즉, 읽기가 많은 경우 사용하는 것이 좋다. 쓰기 동작에서는 데이터 복제도 일어나기 때문에 성능적으로 더욱 불리하다. 적은 양의 데이터를 다루는데 사용해야합니다.
Queue
// JDK 1.5 이상에서 사용가능
Queue<String> queue = new ConcurrentLinkedQueue<>();
Set
// JDK 1.2 이상에서 사용가능
Set<String> set0 = Collections.synchronizedSet(new HashSet<String>());
// JDK 1.6 이상에서 사용가능
Set<String> set2 = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
// JDK 1.8 이상에서 사용가능
Set<String> set3 = ConcurrentHashMap.newKeySet();
Collections.synchronizedSet 과 ConcurrentHashMap을 이용한 Set을 비교해보면,
Collections.synchronizedSet은 Set 전체에 대해 lock을 잡고 ConcurrentHashMap은 부분적으로 lock을 잡기 때문에 ConcurrentHashMap을 이용하는 것이 성능에 유리합니다.
대신 Collections.synchronizedSet은 Set의 다양한 구현체들을 활용 가능합니다. 예를들어, EnumSet과 같은 Set도 적용 가능합니다.
SortedSet
// JDK 1.2 이상에서 사용가능
Set<String> set1 = Collections.synchronizedSortedSet(new TreeSet<String>());
// JDK 1.6 이상에서 사용가능
Set<String> set2 = new ConcurrentSkipListSet<>();
Collections.synchronizedSortedSet과 ConcurrentSkipListSet을 비교해보면,
Collections.synchronizedSortedSet은 Set 전체에 대해 lock을 잡고 ConcurrentSkipListSet은 부분적으로 lock을 잡기 때문에 ConcurConcurrentSkipListSet이 성능에 유리합니다.
Map
// JDK 1.2 이상에서 사용가능
Map<String, String> map0 = Collections.synchronizedMap(new HashMap<String, String>());
// JDK 1.5 이상에서 사용가능
Map<String, String> map1 = new ConcurrentHashMap<String, String>();
Collections.synchronizedMap과 ConcurrentHashMap을 비교해보면,
Collections.synchronizedMap은 Map 전체에 대해 lock을 잡고 ConcurrentHashMap은 부분적으로 lock을 잡기 때문에 ConcurrentHashMap이 성능에 유리합니다.
대신 Collections.synchronizedSet은 Map의 다양한 구현체들을 활용 가능합니다. 예를들어, EnumMap과 같은 Map도 적용 가능합니다.
SortedMap
// JDK 1.2 이상에서 사용가능
Map<String, String> map0 = Collections.synchronizedSortedMap(new TreeMap<>());
// JDK 1.6 이상에서 사용가능
Map<String, String> map1 = new ConcurrentSkipListMap<>();
Collections.synchronizedSortedMap과 ConcurrentSkipListMap을 비교해보면,
Collections.synchronizedSortedMap은 Map 전체에 대해 lock을 잡고 ConcurrentSkipListMap은 부분적으로 lock을 잡기 때문에 ConcurrentSkipListMap이 성능에 유리합니다.
Associated Posts
관련된 주제를 살펴볼 수 있도록 동일한 Tag를 가진 글들을 모아뒀습니다. 제목을 눌러주세요.-
유용한 표준 Java RuntimeException
( 이미지 출처 : https://openjdk.java.net )Java 프로그래밍을 하면서 예외처리를 발생시켜야하는 경우, 우리는 RuntimeException을 상속하는 예외를 사용하면 됩니다.
그리고 RuntimeException을 상속하는 예외를 새롭게 만드는 것보다는 JDK에서 제공하는 표준 RuntimeExcepton 상속 예외들을 사용하는 것이 바람직합니다.JDK 12 기준으로 RuntimeException을 직접 상속하는 예외는 총 58개입니다. (참고 - OpenJdk 12 RuntimeException)
그리고 그 58개의 예외들을 다시 상속하는 자식 예외들까지 개수를 세면 엄청나게 많습니다.그 중 자주 사용하게 되는 유용한 표준 RuntimeException 들을 기록합니다.
... 더 읽기 -
Java Random - ThreadLocalRandom, SplittableRandom, SecureRandom
( 이미지 출처 : https://openjdk.java.net )Java에서 제공하는 Random 라이브러리에 대해서 알아봅니다.
... 더 읽기 -
Java Date - Instant, LocalDateTime, ZonedDateTime
( 이미지 출처 : https://openjdk.java.net )JDK 8부터는 Instant, LocalDateTime , ZonedDateTime 등이 추가됐다. 이 들은 immutable하고 thread-safe 하기 때문에 더 편하고 안전하게 날짜와 시간을 다룰 수 있게 되었습니다.
Date의 대부분의 기능은 JDK 1.1부터 deprecated 되었고 JDK 7까지는 Calendar 혹은 GregorianCalendar를 이용해서 날짜와 시간을 다뤄왔지만 JDK 8부터는 그럴 필요가 없어졌습니다.
... 더 읽기 -
Java Validation - null check, Optional
-
How to initialize Java variables - Array, List, Set, Map
-
Java 변수 선언 & 초기화 방법 - Array, List, Set, Map
-
왜 Java 8 을 공부해야 하는가?