✅🌲강의 복습 노트/패캠 JavaSpring 강의,코드 복습
Part2. 6-22 멀티 Thread 프로그래밍에서의 동기화
들판속초록풀
2025. 12. 25. 17:20
critical section 과 semaphore
- critical section 은 두 개 이상의 thread가 동시에 접근 하는 경우 문제가 생길 수 있기 때문에 동시에 접근할 수 없는 영역
- semaphore 는 특별한 형태의 시스템 객체이며 get/release 두 개의 기능이 있다.
- 한 순간 오직 하나의 thread 만이 semaphore를 얻을 수 있고, 나머지 thread들은 대기(blocking) 상태가 된다.
- semaphore를 얻은 thread 만이 critical section에 들어갈 수 있다.

노란색 부분이 critical section 이다.
일종의 열쇠 자물쇠가 있어서 세마포를 가진 스레드만이 critical section에 진입할 수 있다.
critical section 영역은 일종의 메서드가 될 수도 있는데
이 메서드가 공유 자원(임계 영역)을 사용하는 곳인 것이다.
이 부분의 수행을 일종의 열쇠 역할을 하는 세마포를 겟을 해서 이 영역으로 들어간 후 잠군다
나머지 쓰레드들은 대기상태(Block 상태)가 된다. 그 후 다 끝나면 다음 쓰레드가 들어간다.
밑에 코드에서 쓰레드는 Park , ParkWife 이렇게 2개이고
공유 자원은 Bank 클래스(money 멤버변수)이다.
그리고 이 값에 대한 연산이 진행되는 부분은 saveMoney , minusMoney 라는 메서드들이다.
이게 바로 critical section 이다. (임계 영역)
sleep 메서드는 Thread의 static 메서드여서 클래스이름으로 참조하면 된다. Thread.sleep();
saveMoney 와 minusMoney 에 synchronized 를 해줘야 오류가 나지 않는다.
그래서 공유 자원에 대한 다른 메서드들의 접근을 막는다
- Park 과 ParkWife 가 동시에 Bank 자원에 접근하여 작업이 이루어지는 경우의 예제
class Bank{
private int money = 10000;
public synchronized void saveMoney(int save){
int m = this.getMoney();
try {
Thread.sleep(3000); // 3초 , 1000이 1초
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setMoney( m + save);
}
public synchronized void minusMoney(int minus){
int m = this.getMoney();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setMoney( m - minus);
}
public int getMoney(){
return money;
}
public void setMoney(int money){
this.money = money;
}
}
class Park extends Thread{
public void run(){
System.out.println("start save");
SyncMain.myBank.saveMoney(3000);
System.out.println("saveMoney(3000): " + SyncMain.myBank.getMoney() );
}
}
class ParkWife extends Thread{
public void run(){
System.out.println("start minus");
SyncMain.myBank.minusMoney(1000); // myBank 는 static 참조변수
System.out.println("minusMoney(1000): " + SyncMain.myBank.getMoney() );
}
}
public class SyncMain {
public static Bank myBank = new Bank(); // static 참조변수
public static void main(String[] args) throws InterruptedException {
Park p = new Park();
p.start();
Thread.sleep(200);
ParkWife pw = new ParkWife();
pw.start();
}
}
동기화 (synchronization)
- 두 개의 thread 가 같은 객체에 접근 할 경우, 동시에 접근함으로써 오류가 발생
- 동기화는 임계영역에 접근한 경우 공유자원을 lock 하여 다른 thread의 접근을 제어
- 동기화를 잘못 구현하면 deadlock에 빠질 수 있다.
자바에서는 1. synchronized 메서드나 2. synchronized 블럭을 사용
synchronized 블럭
- 현재 객체(this) 또는 다른 객체를 lock으로 만든다.
- 동기화 블럭 ( ) 안에다가 객체를 넣는다
동기화 블럭이 있는 메서드가 수행되는 동안
( ) 안에 있는 객체에 Lock 을 걸어라 라는 뜻이다.
이 객체를 다른 메서드가 사용하지 못하게 한다
synchronized(참조형 수식) { // 참조형 수식은 주로 객체 변수
수행문;
}
synchronized 메서드
- 객체의 메소드에 synchronized 키워드 사용
- 현재 이 메서드가 속해있는 객체에 lock을 건다.
- 자바에서는 deadlock을 방지하는 기술이 제공되지 않으므로 되도록이면 synchronized 메서드에서
다른 synchronized 메서드는 호출하지 않도록 한다. - deadlock의 예 (deadlock : 두 쓰레드가 서로가 끝나야 수행이 진행될 수 있는데 둘 다 안 끝나는 경우)
이 경우 쓰레드를 그냥 종료시켜야 한다. deadlock 상황은 피해야 한다.
