본문 바로가기
자바

Thread Synchronized

by blog-yj 2020. 4. 19.

쓰레드 배타제어


멀티 쓰레드 프로그램에서는 복수의 쓰레드가 자유롭게 동작한다.

그리고 같은 인스턴스를 동시에 조작하는 경우도 있다. 하지만 이것은 경우에 따라서 곤란한 상황을 야기한다. 


예를 들어 은행 계좌에서 돈을 인출한다고 해보자.


예금 잔고를 체크해서 필요금액 이상이 있으면 필요금액 만큼 인출하여 예금 잔고를 줄인다.  이렇게 하면 예금 잔고가 마이너스가 될 일은 없다.


하지만 2가지 쓰레드가 병행하여 실행 할 경우 예금잔고가 마이너스가 될 수 있다.

어째서일까?


쓰레드 A와 쓰레드 B가 병행하여 동작하는 경우 타이밍에 따라서는 쓰레드 A의 잔고 확인과 잔고를 줄이는 처리 라고 하는 2개 처리 사이의 쓰레드 B의 처리가 끼어들 가능성이 있기 떄문이다!!


쓰레드 A와 쓰레드 B가 경쟁함으로써 예기치 않게 발생하는 이러한 상황을 데이터 레이스 (data race)혹은 레이스 컨디션 (race condition)이라 부른다.


data race를 방지하기 위해선 일종의 교통정리가 필요하다.

예를 들어 하나의 쓰레드가 어느 부분을 실행하고 있으면 다른 쓰레드가 그 부분을 실행 할 수 없게 만드는 것이다. 이러한 교통정리를 일반적으로 배타제어 혹은 상호배타 라고 하며 JAVA에서는 쓰레드의 배타제어를 실행할 때에 synchronized라고 하는 키워드를 사용한다.


synchronized 메소드


메소드에 synchronized라고 하는 키워들르 붙여서 선언하면 그 메소드는 하나의 쓰레드로 동작한다. 이것은 한 번에 한개 쓰레드만 실행시킬 수 있다는 의미이다. 이러한 쓰레드를 synchronized 메소드 혹은 동기 메소드라고 부른다.


예제를 보자



위의 소스에서 Bank 클래스는 deposit, withdraw (예금,인출)라고 하는 2개의 synchronized 메소드가 있다.


하나의 쓰레드가 Bank 인스턴스의 deposit 메소드를 실행하는 중에는 다른 쓰레드가 동일한 인스턴스의 deposit 메소드나 withdraw메소드를 실행할 수 없다.


하지만 Bank 클래스에는 getUserName이라는 메소드가 있는데 이것은 동기 메소드가 아니므로 deposit이나 withdraw를 다른 쓰레드가 실행 중이든 아니든 관계없이 언제든지 실행할 수 있다.



위 처럼 하나의 쓰레드가 deposit 또는 widthdraw를 실행하는 경우에 lock을 취한다고 표현한다. 이 메소드의 실행이 끝나야 lock이 풀리며 다른 쓰레드가 동기 메소드를 실행 할 수 있다.



'자바' 카테고리의 다른 글

Thread Wait, Notify, NotifyAll  (0) 2020.04.19
Thread Sleep  (0) 2020.04.19
How to Excute Thread!?  (0) 2020.04.19
Thread - [multi Thread]  (0) 2020.04.19
Thread [single Thread]  (0) 2020.04.19