Skip to content

Latest commit

 

History

History
71 lines (60 loc) · 2.79 KB

조윤호.md

File metadata and controls

71 lines (60 loc) · 2.79 KB

[Java] Synchronization - 조윤호

Atomic(원자성)

  • 공유 자원에 대한 작업의 단위가 더 이상 쪼갤 수 없는 하나의 연산인 것 처럼 동작하는 것

Visibility(가시성)

  • CPU는 각각 메모리에 대한 캐시를 갖고 있고, writeback 방법(메모리에 직접 수정하지 않고, 캐시에 1차 수정 후 메모리에 일괄 수정하는 방식)을 사용한다.
  • 일반적인 변수의 경우 한 cpu에서의 수정은 다른 cpu에 바로 반영되지 않는다(캐싱 효율을 위해).
image
  • volatile 로 변수를 선언하여 가시성 확보 -> 수정된 데이터가 바로 flush(캐시->메모리로 데이터 이동)된다.
  • 하지만, 원자성 문제 (동시에 같은 값을 읽어다 증가시키고 flush하는...)로 인해 가시성이 100% 보장되지는 않음
private volatile value

Blocking (블로킹)

모니터

  • Mutual exclusion queue에 프로세스 대기, 순차적으로 임계영역 접근
  • 상호 배타, 실행순서 정렬 제공
// 메서드 전체를 임계 영역으로 설정하기public synchronized void mySyncMethod() ... {
  ...
}

// 특정한 영역을 임계 영역으로 설정
synchronized(객체의 참조변수) {
  ...
}
  • 성능 개선
    • 임계영역의 사용을 최소화할것
    • 공유자원,전역변수 되도록 사용하지 않을 것
  • 단점
    • 큐에서의 대기로 인한 성능저하 발생
    • 데드락 발생 가능

wait() and notify()

  • wait() : 객체의 lock을 풀고 쓰레드를 해당 객체의 waiting pool에 넣는다.
  • notify() : waiting pool에서 대기중인 쓰레드 중 하나를 깨운다.
  • notifyAll() :waiting pool에서 대기중인 모든 쓰레드를 깨운다.

Non-Blocking (논블로킹)

  • 다른 스레드의 작업여부와 상관없이 자신의 작업을 수행

CAS 알고리즘 (Compile and Set)

  1. 연산 전의 값을 저장(=기댓값) 후 연산 수행
  2. 연산 결과를 저장하기 전, 기댓값과 기존 자원의 값을 비교
  3. 만약 다르다면 수정하지 x, False 반환

atomic 타입 변수 = CAS + Volatile

private AtomicInteger value = new AtomicInteger(0);
  • volatile 변수로 선언됨
  • compareAndSet 메소드 실행
public class AtomicInteger extends Number implements Serializable {
    private static final long serialVersionUID = 6214790243416807050L;
    private static final Unsafe U = Unsafe.getUnsafe();
    private static final long VALUE;
    private volatile int value;

    //...
    public final boolean compareAndSet(int expectedValue, int newValue) {
        return U.compareAndSetInt(this, VALUE, expectedValue, newValue);
    }
}