[Java] 자바의 스레드(Thread)와 동기화(Synchronization) (3)


바로가기 >> 자바의 스레드와 동기화 (1)

바로가기 >> 자바의 스레드와 동기화 (2)

 

동기화(Synchronization)
동기화란 여러 개의 스레드가 한 개의 자원을 사용하고자 할 때 해당 스레드만 제외하고 나머지는 접근하지 못하도록 하는것을 의미한다.

자바 동기화는 synchronized 식별자를 사용하며 2가지 방법을 지원한다.

1. 동기화 메소드 사용 방법

접근지정자 synchronized 리턴타입 메소드명(){}

 

동기화 메소드를 이용한 예제

class Account {

	static int money = 100;

	public synchronized void depositMoney() {
		money++;
		System.out.println("만원 입금 잔액은 " + money + "만원");
	}

	public synchronized void withdrawMoney() {
		money--;
		System.out.println("만원 출금 잔액은 " + money + "만원");
	}
}

class Deposit extends Thread {
	Account account;

	public Deposit(Account account) {
		this.account = account;
	}

	public void run() {
		for (int i = 0; i < 5; i++) {
			try {
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			account.depositMoney();
		}
	}
}

class Withdraw extends Thread {
	Account account;

	public Withdraw(Account account) {
		this.account = account;
	}

	public void run() {
		for (int i = 0; i < 5; i++) {
			try {
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			account.withdrawMoney();
		}
	}

}

public class Test {

	public static void main(String[] args) {
		System.out.println("계좌 잔액은 " + Account.money + "만원");
		Account account = new Account();
		Deposit d = new Deposit(account);
		Withdraw w = new Withdraw(account);

		d.start();
		w.start();
		
		try {
			d.join();
			w.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("계좌 잔액은 " + Account.money + "만원");
	}

}

 

 

2. 동기화 블록을 사용하는 방법

접근지정자 리턴타입 메소드명(){
 synchronized(공유객체){
 }
}

동기화 블록을 이용한 예제

class Account {

	static int money = 100;

	public void depositMoney() {
		
		synchronized(this) {
			money++;
			System.out.println("만원 입금 잔액은 " + money + "만원");
		}
	}

	public void withdrawMoney() {
		
		synchronized(this) {
			money--;
			System.out.println("만원 출금 잔액은 " + money + "만원");
		}
	}
}

class Deposit extends Thread {
	Account account;

	public Deposit(Account account) {
		this.account = account;
	}

	public void run() {
		for (int i = 0; i < 5; i++) {
			try {
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			account.depositMoney();
		}
	}
}

class Withdraw extends Thread {
	Account account;

	public Withdraw(Account account) {
		this.account = account;
	}

	public void run() {
		for (int i = 0; i < 5; i++) {
			try {
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			account.withdrawMoney();
		}
	}

}

public class Test {

	public static void main(String[] args) {
		System.out.println("계좌 잔액은 " + Account.money + "만원");
		Account account = new Account();
		Deposit d = new Deposit(account);
		Withdraw w = new Withdraw(account);

		d.start();
		w.start();

		try {
			d.join();
			w.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("계좌 잔액은 " + Account.money + "만원");
	}

}

 

답글 남기기