멀티쓰레드 프로세스의 경우 여러 쓰레드가 같은 프로세스 내의 자원을 공유해서 작업하기 때문에 서로의 작업에 영향을 주게 된다. 한 쓰레드가 특정 작업을 끝마치기 전까지 다른 쓰레드에 의해 방해 받지 않도록 하는 것이 필요하다. 따라서 필요한 것이 임계 영역(critical section)과 잠금이다.
한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간섭하지 못하도록 막는 것을 쓰레드의 동기화(synchronization) 라고 한다.
메서드 전체 synchronized
class Sync_test implements Runnable {
Account ac = new Account();
@Override
public void run() {
while (ac.getBalance() > 0) {
int money = (int)(Math.random() * 2 + 1) * 100;
ac.wd(money);
System.out.println("balance = " + ac.getBalance());
}
}
}
class Account {
public int getBalance() {
return balance;
}
private int balance = 500;
public synchronized void wd(int money) {
if (balance >= money) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance -= money;
}
}
}
public class ExThreadSync {
public static void main(String[] args) {
Runnable test1 = new Sync_test();
Thread th1 = new Thread(test1);
Thread th2 = new Thread(test1);
th1.start();
th2.start();
}
}
synchronized 블럭
class Sync_test implements Runnable {
Account ac = new Account();
@Override
public void run() {
while (ac.getBalance() > 0) {
int money = (int)(Math.random() * 2 + 1) * 100;
ac.wd(money);
System.out.println("balance = " + ac.getBalance());
}
}
}
class Account {
public int getBalance() {
return balance;
}
private int balance = 500;
public void wd(int money) {
synchronized (this) {
if (balance >= money) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
balance -= money;
}
}
}
}
public class ExThreadSync {
public static void main(String[] args) {
Runnable test1 = new Sync_test();
Thread th1 = new Thread(test1);
Thread th2 = new Thread(test1);
th1.start();
th2.start();
}
}
임계 영역은 멀티쓰레드 프로그램의 성능을 좌우하기 때문에 가능하면 메서드 전체에 락을 거는 것보다 synchronized블럭으로 임계 영역을 최소화해서 보다 효율적인 프로그램이 되도록 해야 한다.
'프로그래밍 > JAVA' 카테고리의 다른 글
프로세스와 쓰레드 2 (0) | 2021.10.02 |
---|---|
쓰레드 wait()과 notify() (0) | 2021.09.29 |
쓰레드 실행제어 (0) | 2021.09.26 |
쓰레드 상태 및 과정 (0) | 2021.09.24 |
쓰레드 IO블락킹과 데몬쓰레드 (0) | 2021.09.23 |