JAVA3_08_쓰레드의 동기화

16918 단어 JavaJava

쓰레드의 동기화 synchronization

  • 멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다.
  • 진행 중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 '동기화'가 필요하다
  • 쓰레드의 동기화 : 한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간섭하지 못하게 막는 것

동기화 원리?

  • 동기화하려면 간섭받지 않아야 하는 문장들을 '임계 영역'으로 설정
  • 임계영역은 락(lock)을 얻는 단 하나의 쓰레드만 출입가능(객체 1개에 락 1개)

synchronized를 이용한 동기화

  • synchronized로 임계영역(lock이 걸리는 영역, critical section)을 설정하는 방법 2가지

1. 메소드 전체를 임계영역으로 지정

public synchronized void calcSum() {
	//...
}


2. 특정한 영역을 임계 영역으로 지정

synchronized(객체의 참조변수) {
	//...
}



ex13_12

synchronized 안하면


public class Ex13_12 {

	public static void main(String[] args) {
		Runnable r = new RunnableThread1();
		new Thread(r).start();
		new Thread(r).start();

	}

}

class Account{
	private int balance = 1000;	//잔고
	//***private으로 해야 동기화가 의미가 있다.
	
	public int getBalance() {return balance;}
	
	public void withdraw(int money) {
		if(balance >= money) {
			try {
				Thread.sleep(1000);	//결과를 보기 쉽게 하기 위함
			} catch (InterruptedException e) {}
			balance -= money;
		}
	}//withdraw
}

class RunnableThread1 implements Runnable{
	Account acc = new Account();
	
	public void run() {
		while(acc.getBalance() > 0) {
			//***0<= x < 4의 정수 0,1,2,3 * 100 = 0, 100, 200, 300
			int money = (int)(Math.random()*3 + 1) * 100;
			acc.withdraw(money);
			System.out.println("balance: "+ acc.getBalance());
		}
	}
}

balance: 900
balance: 900
balance: 700
balance: 700
balance: 200
balance: 200
balance: 0
balance: -200

synchronized 하면


public class Ex13_12 {

	public static void main(String[] args) {
		//***
		Runnable r = new RunnableThread1();
		new Thread(r).start();
		new Thread(r).start();

	}

}

class Account{
	private int balance = 1000;	//잔고
	//***private으로 해야 동기화가 의미가 있다.
	
	public synchronized int getBalance() {return balance;}
	//***읽을 때도 붙여야 한다. 읽는 동안 값이 바뀌면 안되니까!!
	public synchronized void withdraw(int money) {
		if(balance >= money) {
			try {
				Thread.sleep(1000);	//결과를 보기 쉽게 하기 위함
			} catch (InterruptedException e) {}
			balance -= money;
		}
	}//withdraw
}

class RunnableThread1 implements Runnable{
	Account acc = new Account();
	
	public void run() {
		while(acc.getBalance() > 0) {
			//***0<= x < 4의 정수 0,1,2,3 * 100 = 0, 100, 200, 300
			int money = (int)(Math.random()*3 + 1) * 100;
			acc.withdraw(money);
			System.out.println("balance: "+ acc.getBalance());
		}
	}
}

balance: 800
balance: 800
balance: 500
balance: 300
balance: 100
balance: 100
balance: 0



Ref

좋은 웹페이지 즐겨찾기