멀티 쓰레드 프로세스에는 다른 쓰레드의 작업에 영향을 미칠 수 있다.
진행중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 '동기화'가 필요
쓰레드의 동기화 - 한 쓰레드가 진행중인 작업을 다른 쓰레드가 간섭하지 못하게 막는 것
동기화하려면 간섭받지 않아야 하는 문장들을 '임계 영역'으로 설정
임계영역은 락(lock)을 얻은 단 하나의 쓰레드만 출입가능(객체 1개에 락1개)
// 1. 메서드 전체를 임계영역으로 지정
public synchronized void calcSum(){
}
// 2. 특정한 영역을 임계 영역으로 지정
synchronized(객체의 참조변수) {
}
예시 방법 1)
public synchronized void withdraw(int money)
//임계영역을 주어 동기화한 메서드
{
if(balance >= money)
{
try
{
Thread.sleep(1000);
}catch (Exception e) {}
balance -= money;
}
}
예시 방법 2)
public void withdraw(int money)
{
synchronized (this){
if(balance>= money)
{
try
{
Thread.sleep(1000);
} catch (Exception e) { }
balance -= money;
}
} // synchronized
}
class Account{
private int balance = 1000;
//private로 인해 동기화가 의미가 있다.
public int getBalance()
{
return balance;
}
public synchronized void withdraw(int money) {
if (balance >= money)
{
try
{
Thread.sleep(1000);
} catch(InterruptedException e) {}
balance -= money;
}
}// withdraw
}
class Runnable implements Runnable{
Account acc = new Account();
public void run() {
while(acc.getBalance() >0)
{
// 100, 200, 300 중의 한 값을 임의로 출금
int money = (int)(Math.random() * 3+ 1) * 100;
acc.withdraw(money);
System.out.println("balance: " + acc.getBalance());
}
}
}