이펙티브자바) 규칙 68, 69

2015. 8. 5. 01:31Language/Java

반응형


규칙 68. Prefer executors and tasks to threads

# Info 01) JDK 1.5 - add java.util.concurrent



  # info_02) 이 패키지에는 실행자 프레임워크(Executor Framework)라는 것이 있음, 인터페이스 기반 Task 실행 프레임워크.

   ex_01)  ExecutorService executor = Executors.newSingleThreadExcutor();

          Runnable을 넘겨 실행 : excutor.excute(runnable);

          자연스레 종료 : executor.shutdown();


  # info_03) 멀티쓰레드를 하기위해 스레드 풀(thread pool)를 사용!

  어떻게 사용하는가? java.util.concurrent.Executors에 보면 된다.

  (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html)

  


tip. Executors.newCachedThreadPool - 작은 프로그램이거나 부하가 크지 않은 서버를 만들 때 사용.

      Executors.newFixedThreadPool - 부하가 심한 환경에 들어갈 서버를 만들 때 사용.


# info_04) 이번 장에서 중요하게 눈여겨봐야할 것은 지금까지 설명한 실행(Excutor)뿐만 아니라 작업의 단위인 Task이다.

Task란? Runnable, Callable 등이 Task이다!

Task실행은? 실행자 서비스(Excutor service)로 실행. 위에서 언급한 ex_01) 참고!!


# info_05) 실행자 프레임워크에는 java.util.Timer를 대신할 ScheduledThreadPoolExecutor가 정의 되어있음.

결론적으로 스케줄을 하기위해 사용하기 편하고 유연성도 훨씬 높은 ScheduledThreadPoolExecutor를 사용하라!


위의 5가지 info를 기억하자~ item 68 End.


규칙 69Prefer concurrency utilities to wait and notify

# Info 01) JDK 1.5 - add high-level concurrency utility

    ㄴ wait, notify를 정확하게 사용하는 것은 어렵기 때문에, 이 고수준 유틸리티들을 반드시 이용해야 한다.

위에서 말한 높은수준의 병행성 유틸리티는 어디에 있는건가? java.util.concurrent 에 있음.

이 유틸리티는 

   1) 실행자 프레임워크(규칙 68)

   2) 병행 컬렉션(concurrent collection)

   3) 동기자(synchronizer)

의 세가지 범주로 나눌 수 있다.

규칙 69에서는 2), 3)에 대해서 알아보기로 하자.


# Info 02) 병행 컬렉션은?

List, Queue, Map등의 표준 컬렉션 인터페이스에 대한 고성능 병행 컬렉션을 제공한다.

이러한 병행 컬렉션은 동기화를 내부적으로 처리한다. 그러므로 컬렉션 외부에서 병행성을 처리하는 것은 불가능하다.

락을 걸어봐야 아무 효과가 없고 프로그램만 느려진다.

Concurrent Collections

Besides Queues, this package supplies Collection implementations designed for use in multithreaded contexts: ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, CopyOnWriteArrayList, and CopyOnWriteArraySet. When many threads are expected to access a given collection, a ConcurrentHashMap

 is normally preferable to a synchronized 

HashMap, and a ConcurrentSkipListMap is normally preferable to a synchronized TreeMap. A CopyOnWriteArrayList is preferable to a synchronized ArrayList when the expected number of reads and traversals greatly outnumber the number of updates to a list.

The "Concurrent" prefix used with some classes in this package is a shorthand indicating several differences from similar "synchronized" classes. For example java.util.Hashtable and Collections.synchronizedMap(new HashMap()) are synchronized. But ConcurrentHashMap is "concurrent". A concurrent collection is thread-safe, but not governed by a single exclusion lock. In the particular case of ConcurrentHashMap, it safely permits any number of concurrent reads as well as a tunable number of concurrent writes. "Synchronized" classes can be useful when you need to prevent all access to a collection via a single lock, at the expense of poorer scalability. In other cases in which multiple threads are expected to access a common collection, "concurrent" versions are normally preferable. And unsynchronized collections are preferable when either collections are unshared, or are accessible only when holding other locks.

Most concurrent Collection implementations (including most Queues) also differ from the usual java.util conventions in that their Iterators provide weakly consistent rather than fast-fail traversal. A weakly consistent iterator is thread-safe, but does not necessarily freeze the collection while iterating, so it may (or may not) reflect any updates since the iterator was created.

 


컬렉션 인터페이스 가운데 일부는 상태 종속 변경 연산(state depended modify operation)으로 확장.

ex)  ConcurrentMap > putIfAbsent(key, value)



# Info 03) 동기자(synchronizer)는 스레드들이 서로를 기다릴 수 있도록 하여, 상호협력이 가능하게 한다.

가장 널리 쓰이는 동기자는 CountDownLatch와 Semaphore가 있다. 


# tip) 특정 구간의 실행시간을 잴 때는 System.currentTimeMillis대신 System.nanoTime을 사용하자!


더욱 더 궁금한 것이 있다면 Java Concurrency in Practice 참조!


END

          









반응형