반응형

전체 글 145

[Effective Java] Item84. 프로그램의 동작을 스레드 스케줄러에 기대지 말라

여러 스레드가 실행 중이면 운영체제의 스레드 스케줄러가 어떤 스레드를 얼마나 오래 실행할지 정합니다. 구체적인 스케줄링 정책은 운영체제마다 다를수 있으므로 정확성이나 성능이 스레드 스케줄러에 따라 달라지는 프로그램이라면 다른 플랫폼에 이식하기 어렵습니다. 견고하고 이식성 좋은 프로그램을 작성하는 가장 좋은 방법은 실행 가능한 스레드의 평균적인 수를 프로세서 수 보다 지나치게 많아지지 않도록 하는 것입니다. 실행 가능한 스레드 수를 적게 유지하는 주요 기법은 각 스레드가 무언가 유용한 작업을 완료한 후에는 다음 일거리가 생길 떄까지 대기하도록 하는 것 입니다. 스레드는 당장 처리해야 할 작업이 없다면 실행돼서는 안 됩니다. 또한, 특정 스레드가 다른 스레드들과 비교해 CPU 시간을 충분히 얻지 못해서 간신..

카테고리 없음 2022.10.02

[Effective Java] Item83. 지연 초기화는 신중히 사용하라

지연초기화 지연 초기화는 필드의 초기화 시점을 그 값이 처음 필요할 때까지 늦추는 기법입니다. 그래서 값이 전혀 쓰이지 않으면 초기화도 일어나지 않습니다. 이 기법은 정적 필드와 인스턴스 필드 모두에 사용할 수 있습니다. 주로 최적화 용도로 쓰이지만, 클래스와 인스턴스 초기화 때 발생하는 위험한 순환 문제를 해결하는 효과도 있습니다. 지연초기화의 단점 지연초기화는 필드 혹은 인스턴스 생성시 초기화 비용은 줄지만 초기화하는 필드에 접근하는 비용은 커집니다. 지연 초기화 하려는 필드들 중 결국 초기화가 이뤄지는 비율에 따라, 실제 초기화에 드는 비용에 따라, 초기화된 각 필드를 얼마나 빈번히 호출하느냐에 따라 지연 초기화가 실제론느 성능을 느려지게 할 수도 있습니다. 멀티스레드 환경 멀티스레드 환경에서는 지..

카테고리 없음 2022.10.01

[Effective Java] Item82. 스레드 안전성 수준을 문서화하라

멀티스레드 환경에서도 API를 안전하게 사용하게 하려면 클래스가 지원하는 스레드 안전성 수준을 정확히 명시해야합니다. 다음 목록은 스레드 안전성이 높은 순으로 나열한것입니다. 불변: 이 클래스의 인슨턴스는 마치 상수와 같아서 외부 동기화도 필요없습니다. String, Long, BigInteger가 대표적입니다. 무조건적 스레드안전: 이 클래스의 인스턴스는 수정될 수 있으나, 내부에서 충실히 동기화하여 별도의 외부 동기화 없이 동시에 사용해도 안전합니다. AtomicLong, ConcurrentHashMap이 대표적입니다. 조건부 스레드안전: 일부 메서드는 동시에 사용하려면 외부 동기화가 필요합니다. Collections.synchronize 래퍼 메서드가 반환한 컬렉션들이 여기에 속합니다 스레드 안전하..

카테고리 없음 2022.10.01

[Effective Java] Item81. wait와 notify보다는 동시성 유틸리티를 애용하라

wait와 notify는 올바르게 사용하기가 까다로우니 고수준 동시성 유틸리티를 사용하는 것이 좋습니다. 동시성 컬렉션 List, Queue, Map 같은 표준 컬렉션 인터페이스에 동시성을 가미해 구현한 고성능 컬렉션입니다. 동시ㅓㅇ 컬렉션에서 동시성을 무력화하는건 불가능하며, 외부에서 락을 추가로 사용하면 오히려 속도가 느려집니다. 동시성을 무력화하지 못하므로 여러 메서드를 원자적으로 묶어 호출하는 일도 불가능합니다. 그래서 여러 기본 동작을 하나의 원자적 동작으로 묶는 '상태 의존적 수정' 메서드들이 추가되었습니다. 예를 들어 Map의 putIfAbsent(key, value)메서드는 주어진 키에 매핑된 값이 아직 없을 떄만 새 값을 집어넣습니다. 동기화 장치 동기화 장치는 스레드가 다..

카테고리 없음 2022.10.01

[Effecttive Java] Item80. 스레드보다는 실행자, 태스크, 스트림을 애용하라

java.util.concurrent java.util.concurrent 패키지는 실행자 프레임워크라고 하는 인터페이스 기반의 유연한 태스크 실행 기능을 담고 있습니다. ExcutorService exec = Executors.newSingleThreadExcutor(); // 작업 큐 생성 exec.execute(runnable); exec.shutdown(); 실행자 서비스의 주요기능 특정 태스크가 완료되기를 기다립니다. 태스크 모음 중 아무것 하나(invokeAny 메서드) 혹은 모든 태스크(invokeAll 메서드)가 완료되기를 기다립니다. 실행자 서비스가 종료하기를 기다립니다.(awaitTermination 메서드) 완료된 태스크들의 결과를 차례로 받습니다.(ExecutorCompletionS..

카테고리 없음 2022.09.18

[Effective Java] Item79. 과도한 동기화는 피하라

과도한 동기화는 성능을 떨어뜨리고, 교착상태에 빠뜨리고, 심지어 예측할 수 없는 동작을 낳기도 합니다. 응답 불가와 안전 실패를 피하려면 동기화 메서드나 동기화 블록 안에서는 제어를 절대로 클라이언트에 양도하면 안 됩니다. 외부에서 제어 가능한 메서드를 외계인 메서드(alien methoe)라 합니다. public class ObservableSet extends ForwardingSet { public ObservableSet(Set set) { super(set); } private final List observers = new ArrayList(); public void addObserver(SetObserver observer) { synchronized(observers) { observers..

카테고리 없음 2022.09.18

[Effective Java] Item78. 공유중인 가변 데이터는 동기화해 사용하라

synchronized synchronized 키워드는 해당 메서드나 블록을 한번에 한 스레드씩 수행하도록 보장합니다. 아래는 적절히 동기화한 예제 코드입니다. public class StopThread { private static boolean stopRequested; private static synchronized void requestStop() { stopRequested = true; } private static synchronized boolean stopRequested() { return stopRequested; } public static void main(String[] args) throws InterruptedException { Thread backgroundThread ..

카테고리 없음 2022.09.18

[Effective Java] Item77. 예외를 무시하지 말라

try { ... }catch(SomeException e){ // 아무것도 안해요 } 위와 같이 catch 블록을 비워두면 예외가 존재할 이유가 없습니다. 예외 무시 FileInputStream은 입력 전용 스트림이므로 파일의 상태를 변경하지 않았으니 복구할 것도 없습니다. 또한, 스트림을 닫는다는 것은 이미 파일을 다 읽었다는 뜻이므로 작업을 중단할 필요도 없습니다. 이런경우 예외를 무시해도 됩니다. 예외를 무시하기로 했다면 catch 블록안에 코멘트를 달아주는 것이 좋습니다. Future f = exec.submit(planarMap::chromatioNumber); int numColors = 4; // 기본값 try { numColors = f.get(1L, TimeUnit.SECONDS); }..

카테고리 없음 2022.09.18

[Effective Java] Item 76. 가능한 한 실패 원자적으로 만들라

실패 원자적 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다는 내용입니다. 실패 원자적으로 만드는 방법 불변 객체로 설계 불변 객체는 태생적으로 실패 원자적입니다. 메서드가 실패하면 새로운 객체가 만들어지지는 않을 수 있으나 기존 객체가 불안정한 상태에 빠지는 일이 없습니다. 불변 객체의 상태는 생성 시점에 고정되어 절대 변하지 않기 때문입니다. 작업 수행에 앞서 매개변수의 유효성 검사 public Object pop() { if(size == 0){ throw new EmptyStackException(); } Object result = elements[--size]; elements[size] = null; // 다쓴 참조 해제 return result; } if 문이..

[Effective Java] Item75. 외의 상세 메시지에 실패 관련 정보를 담으라

자바에서는 기본적으로 예외를 잡지못해 프로그램이 실패하면 예외의 스택 추적 정보를 자동으로 출력합니다. 이는 예외가 발생했을 때 프로그램이 실행중에 호출한 메서드의 리스트로 일반적으로는 예외 객체의 toString 메서드를 호출해 얻은 문자열입니다. 이는 예외 분석의 유일한 정보일 때가 많으므로 가능한 한 많은 정보를 담는 것이 좋습니다. 그러므로 발생한 예외에 관여된 모든 매개변수와 필드의 값을 실패 메시지에 담는 것이 좋습니다.

카테고리 없음 2022.08.28