멀티 Thread 프로그래밍에서의 동기화
critical section과 semaphore
- critical section 은 두 개 이상의 thread가 동시에 접근하는 경우 문제가 생길 수 있기 때문에 동시에 접근할 수 없는 영역
- semaphore는 특별한 형태의 시스템 객체이며 get/release 두 개의 기능이 있다.
- 한 순간 오직 하나의 thread 만이 semaphore를 얻을 수 있고, 나머지 thread들은 대기(blocking) 상태가 된다.
- semaphore를 얻은 thread 만이 critical section에 들어갈 수 있다.
노란색이 critical section
// 일종의 메서드 구간이 될 수도 있고 블록 구간이 될 수도 있다.
// 열쇠 get()으로 들어가서 잠근다.
// 다른애들은 사용 불가 대기 상태 ( 일종의 경쟁 상태)
// 수행 끝나면 열어놓는다 release()
동시에 접근할 수 없어서 생기는 문제 - 2가지 상황
- 리소스가 하나인데 동시에 접근하는 경우
- 리소스가 여러개여서 여러 쓰레드가 나눠가질 수는 있는데 리소스가 한정되어있어서 웨이팅 발생하는 부분
동시에 접근할 수 없어서 생기는 문제 예제
Park 과 ParkWife 가 동시에 Bank 자원에 접근하여 작업이 이루어지는 경우의 예제
은행 클래스 생성
- 은행에 현재 돈이 있고 - 입금 메서드(3초 sleep) / 출금 메서드(0.2초 sleep) 생성.
Thread 2개 생성
3,000 원 입금 Thread - Park 생성
1,000 원 출금 Thread - ParkWife 생성
두 Thread 의 shared resource는 bank로 SyncMain 클래스에 static변수로 선언되어있다.
-> SyncMain.mybank 이거 가져다가 사용

출력 테스트
입출력 잘 되는지 , money 값 맞는지 확인
2개 Thread 돌릴것이다.
2개 Thread 종료 되었을 때 setMoney 값 확인
나온 이유
saveMoney 가 시작되고 그다음에 minusMoney가 시작되었지만
saveMoney(3000)이 실행되고 있는 중인 3초 사이에
minusMoney(1000)이 실행되고 먼저 완료 -
그 다음 3초 다 기다린 saveMoney(3000) 실행
먼저 불린 saveMoney()에서 getMoney로 가져온 값이 10,000이고 3초를 기다린다.
다음 불린 minusMoney()에서 getMoney로 가져온 값이 10,000 이고 0.2초 뒤에 10,000-1000 해서 money = 9000으로 set 해서 완료 - ParkWife Thread 종료
3초를 다 기다린 뒤 saveMoney() 남은 수행문 수행 - 가져온 money값 10,000원 + 3,000 원해서 money = 13,000으로 set 해서 완료
여기서 문제점
- 3초 기다린 뒤 수행할 때 중간에 minusMoney( )로 바뀐 bank의 money값이 아닌
- saveMoney( )에서 처음 실행될 때 세팅해놓은 기존의 money값 (10,000원)에 남은 부분(+3,000) 수행했다.
- 먼저 수행되고 있던 saveMoney()가 끝나기 전에 minusMoney( )가 들어와서 오류가 발생
-두 개의 Thread가 같은 객체에 동시에 접근할 경우 먼저 수행되고 있는 Thread의 수행이 끝나기 전까지 다른 Thread는 접근을 못하게 하는 것 필요
- saveMoney()가 수행되는 동안 다른 Thread는 접근 금지 - 동기화 필요 - synchronization
동기화 (synchronization)
- 두 개의 thread 가 같은 객체에 접근할 경우, 동시에 접근 함으로써 오류가 발생
- 동기화는 임계 영역에 접근한 경우 공유자원을 lock 하여 다른 thread의 접근을 제어
- 동기화를 잘못 구현하면 deadlock에 빠질 수 있다.
start save 가 실행되고 star minus 까지는 수행됨
공유 리소스 사용하는 부분에서 먼저 수행되고 있는 Thread인 saveMoney 완료될 때까지 3초 기다렸다가
saveMoney() 먼저 수행 완료된 다음
minusMoney() 수행됨을 확인 GOOD :)
이때 minusMoney()는 wait상태
공유하는 리소스 bank를 사용하는 Thread 들에게 synchronized 해준다.
this. 실행되고 있는 Thread - 끝날 때까지 다른 Thread는 접근 제어
자바에서는 synchronized 메서드나 synchronized 블록을 사용
synchronized 블럭
-현재 객체 또는 다른 객체를 lock으로 만든다.
synchronized(참조형 수식) {
수행문;
}
synchronized 메서드
- 객체의 메서드에 synchronized 키워드 사용
- 현재 이 메서드가 속해있는 객체에 lock을 건다.
- 자바에서는 deadlock을 방지하는 기술이 제공되지 않으므로 되도록이면 synchronized 메서드에서 다른 synchronized 메서드는 호출하지 않도록 한다.
- deadlock의 예
자바에서는 데드락에 대한 솔루션은 없다
다만 ynchronized 메서드에서 다른 synchronized 메서드는 호출하지 않도록 데드락 방지 공고
Thread를 exit 시켜야지 풀린다. 어떻게든. 하려면
review
멀티 Thread 프로그래밍에서의 동기화 - synchronized 메서드와 synchronized 블럭
두 개 이상의 thread가 동시에 접근하는 경우 문제가 생길 수 있기 때문에
공유자원을 lock 하여 다른 thread의 접근을 제어
동시에 접근할 수 없도록 동기화 작업이 필요!
현재 메서드가 속해있는 객체를 lock 상태로 만드는 synchronized 메서드
현재 객체나 다른 객체를 lock 상태로 만드는 synchronized 블록
다중 프로그래밍 멀티 쓰레드.
말은 많이 들어봤지만 어떤 방식으로 어떻게 작동되는지 몰랐었는데 살펴볼 수 있었다.
우선순위나 동기화 처리를 해주어서 여러 가지 일들을 동시에 처리할 경우에도
실행하고 있는 thread의 결과 값이 변경되거나 반영이 안 되는 손실이 발생하지 않고
내가 원하는 결과가 나오도록 해 주는 것이었다.
'JAVA 웹 개발 패키지 - 패스트캠퍼스 > Chapter6' 카테고리의 다른 글
wait( ) / notify( ) 메서드 (0) | 2022.02.05 |
---|---|
Thread 클래스의 여러 메서드들 (0) | 2022.02.02 |
자바에서 Thread 만들기 (0) | 2022.01.28 |
데코레이터 패턴예제 실습 ) 커피 머신 프로그램 (0) | 2022.01.27 |
직렬화 (serialization) (0) | 2022.01.25 |