티스토리 뷰

출처 : http://winterbe.com/posts/2015/05/22/java8-concurrency-tutorial-atomic-concurrent-map-examples/


글을 쓴지 어연 1년. 본인의 게으름에 치를 떤다. 사설은 관두고 각설, 본문을 게시한다.


ConcurrentMap


  이 ConcurrentMap은 Map 인터페이스를 확장한 것으로 병행 컬렉션 타입중 가장 유용한 기능을 갖는다. Java8에서 이 인터페이스에 새로운 메서드가 추가되었고 이들을 통해 함수형 프로그래밍이 가능해졌다.


  다음 코드를 기반으로 하여 이러한 새로운 메서드를 사용할 것이다.

ConcurrentMap<String, String> map = new ConcurrentHashMap<>();

map.put("foo", "bar");

map.put("han", "solo");

map.put("r2", "d2");

map.put("c3", "p0");


  이제 forEach() 메서드는 BiConsumer 타입의 람다 표현식을 인자로 받아들인다. 이 BiConsumer에는 파라미터로 들어간 맵의 키와 값이 들어간다. 이 메서드는 물론 기존의 맵 내 모든 요소를 순환하는 for-each 구문으로 대체될 수 있다. 순환(iteration)은 현재 실행 스레드에서 순차적으로 수행된다.


map.forEach((key, value) -> System.out.printf("%s = %s\n", key, value));


  그다음 putIfAbsent() 메서드는 맵에 주어진 키에 대해 값이 없는 경우에만 값을 넣는다. 구현체인 ConcurrentHashMap에서는 put() 메서드와 같이 이 메서드는 최소 스레드 안전(thread-safe)하다. 그렇기에 맵에 서로 다른 스레드로 접근할 때 동기화를 걸 필요가 없다.


String value = map.putIfAbsent("c3", "p1");

System.out.println(value);    // p0

  getOrDefault() 메서드는 주어진 키에 등록된 값을 반환한다. 그러나 해당 키에 대해 등록된 값이 없는 경우 인자로 들어간 값이 그대로 반환된다.


String value = map.getOrDefault("hi", "there");

System.out.println(value);    // there


 replaceAll() 메서드는 BiFunction 타입의 람다 표현식을 인자로 받는다. BiFunction들은 두 개의 파라미터를 받아서 한 개의 값을 반환한다. 이 경우 해당 함수(function)는 각 맵 요소(entry)의 키와 값과 함께 호출되고 해당 키에 새 값을 할당한다.


map.replaceAll((key, value) -> "r2".equals(key) ? "d3" : value);

System.out.println(map.get("r2"));    // d3


  replaceAll()은 주어진 맵에 등록된 키와 그에 대응되는 값들에 대해 전부 치환작업을 진행하지만 compute() 를 사용하면 특정 키에 등록된 값만을 변형할 수 있도록 해준다. 이 메서드는 적용될 키와 bi-function 람다식을 파라미터로 취하는데 해당 람다식은 값이 어떻게 변형되어야 하는지에 대한 정보를 담는다.


map.compute("foo", (key, value) -> value + value);

System.out.println(map.get("foo"));   // barbar


  compute()에 이어서 두 개의 유사한 변형 메서드도 제공된다. 대표적으로 computeIfAbsent()와 computeIfPresent()가 있다. 이 메서드에 들어간 람다식은 각각 키가 부재할 경우와 키가 존재할 경우에만 호출된다.


  마지막으로, merge() 메서드가 있다. 이 메서드는 기존 실재하는 값을 새로운 값을 이용해서 변경할 수 있게 해준다. 해당 메서드는 기존 값에 통합될 새로운 값 그리고 bi-function을 파라미터로 받는다. 역시 여기서도 마지막 람다식 파라미터는 통합(merge)를 어떻게 수행할지에 대한 정보를 담는다.


map.merge("foo", "boo", (oldVal, newVal) -> newVal + " was " + oldVal);

System.out.println(map.get("foo"));   // boo was foo


또 시간이 없고 귀찮아졌다. 다음 마지막 남은 건 ConcurrentHashMap인데 이건 나중에 다시 쓸 예정이다. 무기한 예정.


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함