[Java] 멀티 스레드 동기화(multi-threaded synchronization)

2022. 2. 27. 21:17Back-end/Java

임계 구역(critical section)과 세마포어(semaphore)

  • critical section은 여러 개의 thread가 동시에 접근할 수 없는 영역이다
  • semaphore는 특별한 형태의 시스템 객체이며 get/release 두 개의 기능이 있다
  • 한 순간 오직 하나의 thread 만이 semaphore를 얻을 수 있고 나머지 thread들은 대기(blocking) 상태가 된다
  • semaphore를 얻은 thread 만이 critical section에 들어갈 수 있다

 

 

Kh 클래스와 Ys 클래스가 동시에 Bank 클래스에 접근하는 예제
package ch22;

class Bank {

	private int money = 5000;

	public synchronized void saveMoney(int save) {

		int m = this.getMoney();

		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		setMoney(m + save);
		
	} // saveMoney

	public synchronized void spendMoney(int spend) {

		int m = this.getMoney();

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		setMoney(m - spend);
		
	} // minusMoney

	public int getMoney() {
		return money;
	}

	public void setMoney(int money) {
		this.money = money;
	}
	
} // Bank

class Kh extends Thread {

	public void run() {
		System.out.println("save money");
		SyncMain.myBank.saveMoney(5000);
		System.out.println("save money : " + SyncMain.myBank.getMoney());
	}
}

class Ys extends Thread {

	public void run() {
		System.out.println("spend money");
		SyncMain.myBank.spendMoney(1000);
		System.out.println("spend money : " + SyncMain.myBank.getMoney());
	}
}

public class SyncMain {
	
	public static Bank myBank = new Bank();

	public static void main(String[] args) {
		
		Kh kh = new Kh();
		kh.start();
		
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		Ys ys = new Ys();
		ys.start();
		
	} // main

} // SyncMain
[Console]
save money
spend money
save money : 10000
spend money : 9000

 

Bank 클래스의 spendMoney 메서드는 Thread.sleep(1000)이고 saveMoney 메서드는 Thread.sleep(2000)인데 sleep 주기가 더 짧은 spendMoney 메서드가 먼저 실행되지 않고 saveMoney 메서드가 먼저 실행되었다.

 

동기화 (synchronization)

  • 두 개의 thread가 같은 객체에 동시에 접근할 경우 오류가 발생할 수 있다
  • 동기화는 임계 영역에 접근한 경우 공유 자원을 lock 하여 다른 thread의 접근을 제어한다
  • 동기화를 잘못 구현하면 교착 상태(deadlock)에 빠질 수 있다

 

자바에서는 synchronized 블럭이나 synchronized 메서드를 사용한다

synchronized 블럭 : 현재 객체 또는 다른 객체를 lock으로 만든다
synchronized(참조형 수식) {

	// 수행문
}
synchronized 메서드
  • 객체의 메서드에 synchronized 키워드 사용하고, 이 메서드가 속해있는 객체에 lock을 건다
  • 자바에서는 deadlock을 방지하는 기술이 제공되지 않으므로 되도록이면 synchronized 메서드에서 다른 synchronized 메서드는 호출하지 않도록 한다.

 

교착 상태(deadlock)

 

 

반응형