멀티 스레드로 작업 시, 스레드간 작업이 서로 간섭이 되지 않도록 하는 것
멀티 스레드 기법은 자원을 공유하는데, 이 때 동시에 같은 자원을 처리한다면, 자원 값이 실제 처리해야하는 작업보다 더 많은 작업이 발생할 수 있다.
1) 동시에 작업하는 메서드에 synchronized 키워드 걸기
public synchronized void 메서드명(){
//수행할 작업
}
2) synchronized 영역 지정하기
void 메서드명(){
synchronized(스레드객체){
//수행할 작업
}
}
스레드를 대기시키는 wait()메서드와 대기중인 스레드를 깨우는 notify() 메서드를 통한 스레드 제어 알아보기
메서드 | 설명 |
---|---|
void wait() | notify()가 호출될 때까지 대기 |
void wait(long timeout) | timeout 시간만큼 대기 |
notify() | 대기 중인 한 스레드만 깨움 |
notifyAll() | 대기 중인 모든 스레드를 깨움 |
엄마는 입금, 아들은 출금하는 코드
public static void main(String[] args) {
Account account=new Account();
Son son = new Son(account);
Mom mom = new Mom(account);
son.start();
mom.start();
}
}
class Account{
int money=0;
//입금, 출금
public int showMoney() {
return money;
}
public synchronized void setMoney() {
try {
Thread.sleep(1000); //1초 대기
}catch(InterruptedException ie) {System.out.println(ie.toString());}
this.money+=2000;
System.out.println("어머니가 용돈을 입금했습니다. 현재 잔액: " + this.showMoney());
this.notify();
}
public synchronized void getMoney() {
while(money<=0) {
try {
System.out.println("통장 잔고가 없어서 아들 애기 중");
this.wait();
}catch(InterruptedException i) {}
}
this.money-=2000;
System.out.println("아들이 용돈을 출금했습니다. 현재 잔액: "+this.showMoney());
}
}
class Son extends Thread{
private Account account;
Son(Account account){
this.account=account;
}
public void run() {
for(int i=0;i<10;i++) {
account.getMoney();
}
}
}
class Mom extends Thread{
private Account account;
Mom(Account account){
this.account=account;
}
public void run() {
for(int i=0;i<10;i++) {
account.setMoney();
}
}
}