스레드 동기화

개발하는개발자·2022년 9월 13일
0

Java Thread

목록 보기
8/10

동기화

멀티스레드의 경우 프로세스와 달리 자원을 공유하기 때문에
서로 간에 간섭을 막기 위해 동기화(Synchronized)를 사용한다.

public synchronized void thread(){}

public void thread(int value){
	synchronized(this){
    	this.value += value;
    }
}

1.메소드 동기화
메서드가 호출된 시점부터 해당 객체의 lock을 얻어 수행 후 메서드가 종료되면 lock을 반환

2.메서드 내의 특정 부분만을 동기화
메소드의 특정 부분에만 동기화가 필요한 경우 해당 부분에 진입하면 객체의 lock을 얻어 수행하고 벗어나면 반환

자바의 모든 객체는 lock을 갖고 있으며 임계 영역의 코드를 수행하기 위해선 객체의 lock을 얻어야 한다.

임계영역 : 둘 이상의 프로세스(쓰레드)가 공유 데이터에 접근하여 작업을 하는 부분의 코드 블록

동기화 블록 메서드

wait() : 스레드를 waiting pool로 보내 대기시킨다.
notify() : waiting pool의 스레드들중 임의의 스레드에 통보한다.
notifyAll() : 모든 스레드에게 통지를 하고, 하나의 스레드가 lock을 얻어 나온다.

Object 정의 메서드

  • 동기화 블록(synchronized블록)내에서만 사용할 수 있다.
  • 보다 효율적인 동기화를 가능하게 한다.

notify()의 경우 waiting pool에 두가지 스레드가 대기 상태로 존재할시 특정 스레드는 계속 통지를 받지 못하는 경우가 있다.
이것을 '기아(Starvation)현상' 이라고 한다.

notifyAll()로 모든 스레드에 통지를 내리더라도, 스레드간에 lock을 얻으려고 하는 '경쟁 상태(race condition)'을 유발한다.

Lock,Condition

자바 concurrent.locks 패키지를 이용해 lock클래스 동기화가 가능하다.

ReentrantLock : 재진입이 가능한 lock. 가장 일반적인 배타 lock
ReentrantReadWritelock : 읽기에는 공유적이고, 쓰기에는 배타적인 lock
StampedLock : ReentrantReadWriteLock에 낙관적 lock 추가

RenntrantLock : 가장 일반적인 lock. 특정 조건에서 lock을 풀고 나중에 다시 lock을 얻고 임계영역으로 들와 이후 작업 수행

ReentrantReadWriteLock : 읽기,쓰기 lock 제공. 읽기 lock이 걸려 있으면, 다른 스레드가 읽기 lock을 중복해서 걸어 읽기를 할 수 있다. (Read는 내용이 바뀌는것이 아니므로 여러 스레드에서 읽는것이 가능)

StampedLock : lock을 걸거나 해지시 스탬프 사용. 위의 lock에서 낙관적 읽기가 추가되었다. 낙관적 읽기 lock은 쓰기 lock에 의해 풀리며 읽기 lock을 얻어 다시 읽어야 한다. 무조건 읽기 lock을 걸지 않고, 쓰고 읽기가 충돌할때만 쓰기가 끝난 후에 읽기 lock을 건다.

profile
하루에 하나씩 배우자

0개의 댓글