공유하는 가변 데이터에 접근 시 동기화 하자 쓰는 메소드 뿐만 아니라 읽는 메소드도 동기화 처리를 해야 한다.32비트 변수에 대한 할당 연산은 원자적으로 처리되기 때문에 동기화가 필요하지 않다.하지만 스레드 간에 공유되는 데이터라면 메모리 가시성을 위해서 동기화 처리가 필요하다.메모리 가시성만 확보하면 되기 때문에 volatile 키워드를 사용해도 된다.int 변수에 대한 ++ 연산은 단일 연산처럼 보이지만 실제로는 3단계로 나뉘어져 있기 때문에 동기화 처리가 필요하다. 지나친 동기화는 피하자 동기화 블록 안에서 외계인 메소드 호출을 하지 말아야 한다. wait와 notify 대신 동시성 유틸리티를 사용하자wait, notify를 사용할 이유가 거의 없다. 직접 사용하는 것은 "동시성 어셈블리 언어"로 ..
자바 메모리 모델을 숨겨주는 덮개를 열고 자바 메모리 모델이 보장하는 기능과 요구사항과 앞선 내용들의 실제 동작 원리에 대해 알아본다. JMM(Java Memory Model)은 변수에 저장된 값이 어느 시점부터 다른 스레드의 가시권에 들어가는지 JVM이 해야하는 최소한의 보장만 할 뿐임. 16.1.2 재배치 서로 다른 스레드가 각자의 상황에 맞는 순서로 명령어를 실행할 수 있음. 재배치 : 특정 작업이 지연되거나 다른 순서로 실행되는 것처럼 보이는 문제 각 스레드 내부에서 일어나는 작업은 다른 스레드와 연결 관계가 없어서 재배치되어 실행될 가능성이 있다. 16.1.3 자바 메모리 모델을 간략하게 설명한다면 미리 발생(happens-before) 재배치가 가능하지만 필수적으로 지켜야 할 순서는 있다. 작..
단일 연산 변수와 대기 상태에 들어가지 않는 넌블로킹 동기화 기법에 대해서 살펴본다. 넌블로킹 알고리즘은 락을 기반으로 하는 방법보다 설계와 구현 모두 훨씬 복잡함.대신 확장성과 활동성을 엄청나게 높여준다. 여러 스레드가 동일한 자료를 놓고 경쟁하는 과정에서 대기 상태에 들어가는 일이 없어서 스케줄링 부하를 대폭 줄여준다. 데드락이나 기타 활동성 문제가 발생할 위험도 없다. 15.1 락의 단점 락 확보 경쟁이 벌어지는 상황에서는 JVM 역시 운영체제 도움을 받는다. 스레드가 락을 확보하기 위해 대기하고 있는 상태에서 대기 중인 스레드는 다른 작업을 전혀 못한다. 이런 상태에서 락을 확보하고 있는 스레드의 작업이 지연되면 락 확보를 위해 대기하던 모든 스레드의 작업이 전부 지연된다. 스레드 실행을 중단했다..
ReentrantLock 은 자바5.0 에서 추가됐으며 암묵적인 락으로 할 수 없는 고급 기능을 가지고 있다. 13.1 Lock 과 ReentrantLock - Lock 인터페이스는 조건없는 락, 폴링 락, 타임아웃이 있는 락, 락 확보 대기상태에 인터럽트를 걸 수 있는 기능을 가진다. - 모든 작업이 명시적이다. public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException(); boolean tryLock(); boolean tryLock( long timeout, TimeUnit unit() throws InterruptedException(); void unlock(); Condition newCon..
병렬 프로그래밍의 성능을 분석, 모니터링, 성능 향상 방법에 대한 내용. 성능 튜닝은 프로그램 내부 구조를 복잡하게 할 수 있음. 일단 정상적으로 동작하도록 만든 후, 튜닝 하는 것이 좋다. 11.1 성능에 대해 - 성능을 높인다는 것은 더 적은 자원을 사용하면서 더 많은 일을 하도록 만드는 것이다. - 여러 개의 스레드를 사용하려 한다면 항상 단일 스레드를 사용할 때보다 성능상의 비용을 지불해야만 한다. 스레드간의 작업 내용 조율(락, 신호 보내기, 메모리 동기화)컨텍스트 스위칭스레드를 생성하거나 제거하는 일스레드의 효율적인 스케줄링 11.1.1 성능 대 확장성 애플리케이션 성능을 측정하는 데이터 - 서비스 시간, 대기 시간, 처리량, 효율성, 확장성, 용량 단일 티어 애플리케이션이 다중 티어 애플리케..
10.1 데드락 자바 프로그램에서 데드락이 발생하면 프로그램을 강제로 종료하기 전에는 영원히 멈춘 상태로 유지된다. 10.1.1 락 순서에 의한 데드락 예제 코드는 데드락이 발생할 여지가 있다. public class LeftRightDeadlock { private final Object left = new Object(); private final Object right = new Object(); public void leftRight() { synchronized(left) { synchronized(right) { doSomething(); } } } public void rightLeft() { synchronized(right){ synchronized(left) { doSomething()..