충분히 쌓여가는
쓰레드의 동기화(synchronization) 본문
쓰레드의 동기화
멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다
진행 중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 '동기화'가 필요
쓰레드의 동기화 - 한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간섭하지 못하게 막는 것
동기화하려면 간섭받지 않아야 하는 문장들을 '임계 영역'으로 설정
임계영역은 lock 얻은 단 하나의 쓰레드만 출입가능(객체 1개에 lock 1개)
synchronized를 이용한 동기화
synchronized로 임계영역(lock이 걸리는 영역)을 설정하는 방법 2가지
한 번에 1개의 쓰레드만 임계 영역에 들어갈 수 있기 때문에 최소화하는 것이 좋다
동기화 되기 전의 코드
음수로 출력됨
class synchronizationTest {
public static void main(String args[]) {
Runnable r = new RunnableEx1();
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
}
}
class Account {
private int balance = 1000; // private로 해야 동기화의 의미가 있음
public int getBalance() {
return balance;
}
public void withdraw(int money) { // synchronized로 메서드를 동기화
if(balance >= money) {
try { Thread.sleep(1000);} catch(InterruptedException e) {}
balance -= money;
}
} // withdraw
}
class RunnableEx1 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:700
balance:700
balance:400
balance:300
balance:200
balance:0
balance:-100
동기화 된 후의 코드
음수가 나올 수가 없음
class synchronizationTest {
public static void main(String args[]) {
Runnable r = new RunnableEx1();
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
new Thread(r).start(); // ThreadGroup에 의해 참조되므로 gc대상이 아니다.
}
}
class Account {
private int balance = 1000; // private로 해야 동기화의 의미가 있음
public synchronized int getBalance() { // 읽을 때도 동기화(synchronized) 해주기
return balance;
}
public synchronized void withdraw(int money) { // synchronized로 메서드를 동기화
if(balance >= money) {
try { Thread.sleep(1000);} catch(InterruptedException e) {}
balance -= money;
}
} // withdraw
}
class RunnableEx1 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:800
balance:700
balance:600
balance:300
balance:100
balance:100
balance:0
balance:0
'Java > JAVA3' 카테고리의 다른 글
람다식(Lambda Expression) (0) | 2023.08.09 |
---|---|
wait()와 notify() (0) | 2023.08.08 |
join(), yield() (0) | 2023.08.07 |
suspend(), resume(), stop() (0) | 2023.08.07 |
sleep(), interrupt() (0) | 2023.08.04 |