[Java] 멀티 Thread 프로그래밍에서의 동기화

rara_kim·2022년 8월 12일
0

Java

목록 보기
22/39
post-thumbnail

critical section 과 semaphore

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

두 사람이 동시에 Bank라는 공유자원에 접근하여 작업이 이루어지는 경우의 예제

  • synchronized키워드를 사용하지 않았을 경우 기대값 12000이 아닌 13000이 나오게 된다.
  • saveMoney()메서드의 sleep(3000)를 기다리는 동안 minusMoney()가 먼저 실행되게 되고, 그 다음 saveMoney()는 미리 가지고 왔던 m(this.getMoney())을 업데이트 없이 실행하기 때문이다.
  • synchronized키워드를 사용하면 먼저 호출된 saveMoney()가 실행된 다음 minusMoney()메서드가 실행되어 문제없이 기대값 12000이 나오게 된다.
class Bank{
	private int money = 10000;
	
    public synchronized  void saveMoney(int save){	
		int m = this.getMoney();
		
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		setMoney( m + save);
	}
	
	public synchronized  void minusMoney(int minus){
			int m = this.getMoney();
			
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			setMoney( m - minus);		
	}
	
	public int getMoney(){
		return money;
	}
	
	public void setMoney(int money){
		this.money = money;
	}
}


class Kim extends Thread{	
	public  void run(){
		System.out.println("start save");
		SyncMain.myBank.saveMoney(3000);
		System.out.println("saveMoney(3000): " + SyncMain.myBank.getMoney());
    }
}

class KimMother extends Thread{
	public void run(){
		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) throws InterruptedException {	
		Kim k = new Kim();
		k.start();
		
		Thread.sleep(200);
		
		KimMother km = new KimMother();
		km.start();
	}
}


동기화(synchronization)

  • 두 개의 Thread가 같은 객체에 접근 할 경우, 동시에 접근 함으로써 오류가 발생한다.
  • 동기화는 임계영역에 접근한 공유자원을 Lock하여 다른 Thread의 접근을 제어한다.
  • 동기화를 잘못 구현하게 되면 DeadLock에 빠질 수 있으므로 주의가 필요하다.

자바에서의 synchronized 사용

synchronized 블럭

현재 객체 또는 다른 객체를 Lock으로 만든다.

synchronized(참조형 수식) {

      수행문;
}

synchronized 메서드

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

profile
느리더라도 꾸준하게

0개의 댓글