본문 바로가기
언어/JAVA

Thread 3 (멀티 스레드 동기화)

by step 1 2021. 5. 29.
반응형

critical section 과 semaphore

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

동기화 (synchronized)

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

함수에 synchronized를 걸면 그 함수가 포함된 해당 객체(this)에 lock을 거는것과 같다.

참고

https://tourspace.tistory.com/54

 

Java의 동기화 Synchronized 개념 정리#1

Java의 동기화 -Synchronized 키워드의 사용 Java를 프로그래밍 하다면 multi-thread로 인하여 동기화를 제어해야하는 경우가 생깁니다. 그래서 흔히 Synchronized 키워드를 사용하는데요 그냥 multi-thread로 동

tourspace.tistory.com

Park과 ParkWife가 동시에 Bank에 접근하는 예제 (위 아래 synchronized 중 하나의 세트만 사용)

package ch67;

class Bank {
	
	private int money = 10000;
	
	public synchronized void saveMoney(int save) {
		
		int m = getMoney();
		
//		3초간 정지
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		setMoney(m + save);
	}

	public synchronized void minusMoney(int minus) {
		
		int m = getMoney();
		
//		0.2초간 정지
		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;
	}
	
	
}

// Thread 생성
class Park extends Thread {
	
	@Override
	public void run() {

//		해당 부분을 lock 건다
		synchronized (SyncMain.myBank) {
			System.out.println("start save");
			SyncMain.myBank.saveMoney(3000);
			System.out.println("saveMoney(3000): " + SyncMain.myBank.getMoney());
		}
		
	}
}

class ParkWife extends Thread {
	
	@Override
	public void run() {

		synchronized (SyncMain.myBank) {
			System.out.println("start minus");
			SyncMain.myBank.minusMoney(1000);
			System.out.println("minusMoney(1000): " + SyncMain.myBank.getMoney());
		}
		
	}
}

public class SyncMain {

	public static Bank myBank = new Bank();
		
	public static void main(String[] args) {
		
		Park p = new Park();
		p.start();
		
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		ParkWife pw = new ParkWife();
		pw.start();
	}
}

 

자바에서는 synchronized 메서드나 synchronized 블럭을 사용

synchronized 블럭

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

       수행문;

}

synchronized 메서드

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

 

반응형

'언어 > JAVA' 카테고리의 다른 글

알고리즘 1  (0) 2021.05.30
wait() / notify() 메서드를 활용한 동기화 프로그래밍  (0) 2021.05.29
Thread 2 (여러 메서드)  (0) 2021.05.29
Thread 1  (0) 2021.05.23
데코레이터 패턴  (0) 2021.05.23