Synchronized기능과 예제

2023. 7. 19. 16:47JAVA

계좌에 100원을 입금하는 고객 1,2를 만들고

 

Synchronized기능을 사용했을때와 안했을때의 차이를 알아보자 

// 계좌에 돈을 입금하는 동작을 수행하는 Thread클래스 설계
class CustomerThread extends Thread{
	
	Account acc;
	
	//constructor
	public CustomerThread(Account acc) {
		this.acc=acc;
	}
	
	@Override
	public void run() {
		acc.add(100); //100원을 입금하는 동작 수행
	}
}

아래 코드의 경우 동기화 처리가 되지 않아 실행하면 거의 동시에 결과가 나옴

 

두 고객이 동시에 100원을 넣었는데 잔액이 200원이 나와 당황할수 있음 

class Account{
	
	int money=0;
	
	//입금기능 - 동기화처리 되지 않은 기능
	//이 add()기능을 동기화 처리하지 않으면 여러스레드가 동시에 기능을 발동하여 문제를 야기할 수 있음.
	//이를 해결하기 위해 동기화 처리라는 것을 함. 방법 2가지 존재함
	void add(int m) {
		System.out.println("입금 작업을 시작합니다.");		
		
		String name = Thread.currentThread().getName();
		System.out.println(name + " - 현재 잔액 : " + money);
		
		//입긍기능코드
		money=money+m;
		
		//일부러 전산처리 시간을 가정하여 오래걸리는 작업 코드..
		for(long i=0; i<45000000000L; i++) {
			new String("aaa");
		}//////////////////////////////////////////////
		
		System.out.println(name + " - 입금 후 잔액 : " + money);
		System.out.println();
	}

방법1.

 

아래 코드를 실행하면 차례대로 입금이 시작됨 대신 한 고객의 작업이 끝날때까지

 

다른 고객에게 아무런 메시지도 뜨지 않아 당황할 수 있음

synchronized void add(int m) {
		System.out.println("입금 작업을 시작합니다.");		
		
		String name = Thread.currentThread().getName();
		System.out.println(name + " - 현재 잔액 : " + money);
	
		//입긍기능코드
		money=money+m;
		
		//일부러 전산처리 시간을 가정하여 오래걸리는 작업 코드..
		for(long i=0; i<45000000000L; i++) {
			new String("aaa");
		}//////////////////////////////////////////////
		
		System.out.println(name + " - 입금 후 잔액 : " + money);
		System.out.println();
	}
}

방법2.

 

아래 코드는 "입금 작업을 시작합니다" 라는 메세지가 둘 다 에게 보여진 후 차례대로 실행됨

void add(int m) {
		System.out.println("입금 작업을 시작합니다.");		
		
		synchronized(this) {
			String name = Thread.currentThread().getName();
			System.out.println(name + " - 현재 잔액 : " + money);
			
			//입긍기능코드
			money=money+m;
			
			//일부러 전산처리 시간을 가정하여 오래걸리는 작업 코드..
			for(long i=0; i<45000000000L; i++) {
				new String("aaa");
			}//////////////////////////////////////////////
			
			System.out.println(name + " - 입금 후 잔액 : " + money);
			System.out.println();
		}
		
	}
}
public class SynchronizedTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		// 계좌 객체
		Account acc = new Account();
		
		// acc계좌에 100원을 입금하고 싶은 고객1
		CustomerThread t1 =new CustomerThread(acc);
		
		// acc계좌에 100원을 입금하고 싶은 고객2
		CustomerThread t2 =new CustomerThread(acc);
		
		//비슷한 시점에 둘다 100원 입금 동작 실행!
		t1.start(); // run()메소드가 자동 발동!
		t2.start(); 
	}
}

동기화 처리 - Thread를 사용하는 것은 비동기 처리를 한다는 것


동기 (Synchronize)   : a 작업이 끝나면 b 작업을 하는것


비동기(Asynchronize) : a 작업을 할때 b 작업도 동시에 하는것

'JAVA' 카테고리의 다른 글

FileInput(파일 입력)  (0) 2023.07.20
Thread Control 예제  (0) 2023.07.19
Runnable  (0) 2023.07.19
Thread(스레드)  (0) 2023.07.19
Collection 클래스들 - Map  (0) 2023.07.18