[JAVA] Thread 동기화

JUNHO YEOM·2022년 12월 9일
0

JAVA

목록 보기
2/14

Thread 동기화

예시 살펴보기

좌석 정보를 예로들어 살펴봅시다.

동기화를 사용하지 않을 때

Thread1 고객1이 접근

1번 좌석 선택
정보 입력
결제  // 결제할 때 시간이 지연됨

Thread2 고객2가 접근

1번 좌석 선택
정보 입력
결제 // 고객1 보다 더 빠르게 결제 -> 고객2가 좌석 예약 성공

Thread가 공유자원을 사용하고 있기 때문에 해당 문제가 발생함
동기화를 통해서 해당 문제를 예방할 수 있음.
병렬처리 -> (동기화) -> 순차처리

동기화를 사용할 때

Thread1 고객1

1번 좌석 선택
정보 입력
결제

해당 자원에 대한 권한을 Thread1에게 줌

Thread2 고객2

고객은 1번 좌석을 선택 하지 못하게 됨


Thread 동기화란

하나의 Thread가 특정 작업을 마치기 전까지 다른 Thread에게 방해받지 않도록
처리하는 것을 말합니다.


공용 객체

공용 객체를 만들기 위해서 class로 정의 합니다.

예제

  • 공용객체에 예금 금액 데이터가 들어가 있다고 가정합니다.
  • 동일한 클래스에서 2개의 Thread를 만듭니다.(Thread class)
  • 공용 객체에서 더이상 출금이 되지 않을 때 까지(0원이 될 때 까지) 예금을 인출

Thread 동기화의 2가지 개념

Lock(락, 잠금) - monitor

좌석정보라는 공유정보를 Thread가 함께 사용하고 있을 때를 가정합니다.
공유객체는 monitor라는 허가권을 가지고 있습니다.
monitor(Lock)은 이용권 같은 개념임.
Thread는 monitor를 획득함으로 써 정보에 접속할 수 있음 (Auth)
monitor를 획득하지 못한 Thread는 정보에 접속할 수 없음 (Blocked)
이런 방식으로 진행되면 자연스럽게 순차처리가 이루어짐

Thread가 공유객체를 오염시키는 것을 막는다.

monitor를 획득하기 위한 keyword

synchronized라는 키워드를 이용해서 monitor를 획득할 수 있습니다.

synchronize 사용 방법

  • method synchronized앞에 붙이기
public synchronized void withdraw(int money) {
	// 코드
}

synchronized 효과

method 호출이 시작되면 lock(monitor)을 획득하고, lock(monitor)을 획득한 Thread만 공용객체에 접근하여 작업할 수 있게 됩니다.

Lock(monitor) 단점

  • method의 실행이 길다(오래걸린다)
  • 메서드 전체를 동기화 시키면 실제 작업 부분만이 아닌, class 전체에 synchronized를 사용하였기 때문에 실제 공유데이터 사용 부분 이외에도 block이 걸립니다.
    이럴 때는 synchronized block을 사용합니다.


Critical Section(임계 영역)

동기화가 진행되는 영역을 말합니다.

메서드 전체를 임계영역으로 만들 때 method앞에 synchronized 사용하기

public synchronized void withdraw(int money) {
	// 코드
}

일정 코드만을 임계영역으로 만들 때 해당 부분만을 synchronized로 감싸주기

synchronized (this) {
	// 해당 block안에서만 동기화가 실행됩니다.
    }


wait 알아보기

임계영역 code가 다 실행되어야 다른 Thread가 실행될 수 있습니다.

  • 너무 오래걸린다(동시처리가 안되기 때문에)
  • 다른 Thread가 오래 기다려야 한다.(비효율 적)

wait() 메서드

현재 실행중인(Critical Section) Thread Lock을 놓고 wait상태로 전환.
해당 임계영역 실행 권한을 임의로 잠시 놓음 -> wait(대기)상태로 들어갑니다.

notify() 메서드

wait에 의해 일시 정지된 Thread중 하나의 Thread에 대해 Runnable 상태로 전환시켜 줍니다.

notifyAll() 메서드

Object's wait pool blocked 상태에 있는 모든 Thread를
runnable 상태로 보내줍니다.

0개의 댓글