멀티 스레드 프로세스에서는 다른 스레드의 작업에 영향을 미칠 수 있다.
진행중인 작업이 다른 스레드에게 간섭받지 않게 하려면 '동기화'가 필요
스레드의 동기화 - 한 스레드가 진행중인 작업을 다른 스레드가 간섭하지 못하게 막는것
동기화 하려면 간섭받지 않아야 하는 문장들을 '임계 영역'으로 설정
임계영역은 락(lock)을 얻은 단 하나의 스레드만 출입가능(객체 1개에 락 1개)
synchronized를 이용한 동기화
- synchronized로 임계영역(lock이 걸리는 영역)을 설정하는 방법 2가지
1. 메서드 전체를 임계 영역으로 지정
public synchronized void calcSum(){
} //임계 영역(critical section)
2. 특정한 영역을 임계 영역으로 지정
synchronized(객체의 참조변수){
//...
}//임계영역(critical section)
동기화 하지 않았을때
Runnable r = new RunnableEx12();
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다
}
}
class Account {
private int balance = 1000;
public int getBalance() {
return balance;
}
public void withdraw(int money){
if(balance >= money) {
try { Thread.sleep(1000);} catch(InterruptedException e) {}
balance -= money;
}
} // withdraw
}
class RunnableEx12 implements Runnable {
Account acc = new Account();
public void run() {
while(acc.getBalance() > 0) {
// 100, 200, 300중의 한 값을 임으로 선택해서 출금(withdraw)
int money = (int)(Math.random() * 3 + 1) * 100;
acc.withdraw(money);
System.out.println("balance:"+acc.getBalance());
}
} // run()
}
balance:900
balance:900
balance:800
balance:500
balance:300
balance:0
balance:-100 한번에 두개의 메서드가 들어가니 음수로 떨어짐
동기화 한후
Runnable r = new RunnableEx12();
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다
}
}
class Account {
private int balance = 1000;
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 RunnableEx12 implements Runnable {
Account acc = new Account();
public void run() {
while(acc.getBalance() > 0) {
// 100, 200, 300중의 한 값을 임으로 선택해서 출금(withdraw)
int money = (int)(Math.random() * 3 + 1) * 100;
acc.withdraw(money);
System.out.println("balance:"+acc.getBalance());
}
} // run()
}
결과
balance:800
balance:700
balance:400
balance:300
balance:200
balance:0
balance:0
'하.. > java' 카테고리의 다른 글
| ch14 람다식 작성하기 (0) | 2021.12.25 |
|---|---|
| ch13 wait()과 notify() (0) | 2021.12.25 |
| ch13 join() yield() (0) | 2021.12.25 |
| ch13 스레드 실행 일시정지suspend() 재개 resume() 완전정지 stop() (0) | 2021.12.25 |
| ch13 스레드 실행제어 sleep() interrupt() (0) | 2021.12.25 |