Thread Synchronization(쓰레드 동기화) - #4

김병우·2024년 3월 12일
0

Java-Thread

목록 보기
4/5

이번에도 공부하며 실습한 코드는 https://github.com/helloJosh/nhn-homework-thread-study 에 올리겠습니다
-0317 Synchronized 내용추가

1. Thread 동기화

멀티 쓰레드를 사용할 경우 공동으로 사용하는 메모리를 update할 경우 문제가 발생한다.

바로 코드로 알아보자

public class SharedCounterV0 extends Thread{    
    SharedCountV0 sharedCount;
    int count;
    int maxCount;

    public SharedCounterV0(String name, int maxCount, SharedCountV0 sharedCount) {
        setName(name);
        this.sharedCount = sharedCount;
        this.maxCount = maxCount;
        count = 0;
    }

    @Override
    public void run() {
        while (count < maxCount) {
            count++;
            sharedCount.increment();
        }
    }
}
public class SharedCountV0 {    
    int count;
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    public void increment() {
        setCount(getCount() + 1);
    }
}
public static void main(String[] args) throws InterruptedException {        
        SharedCountV0 sharedCount = new SharedCountV0();
        SharedCounterV0 counter1 = new SharedCounterV0("counter1", 10000, sharedCount);
        SharedCounterV0 counter2 = new SharedCounterV0("counter2", 10000, sharedCount);

        counter1.start();
        counter2.start();
        System.out.println(counter1.getName() + ": started");
        System.out.println(counter2.getName() + ": started");

        counter1.join();
        counter2.join();
        System.out.println(counter1.getName() + ": terminated");
        System.out.println(counter2.getName() + ": terminated");

        System.out.println("sharedCount : " + sharedCount.getCount());
    }

이렇게 결과 화면으로 20000 결과가 아닌 12833으로 다른 결과가 나온 것을 알 수 있다.

해결방법

  • 메소드 앞에 Synchronized Method를 붙이거나
public synchronized void increment() {
        setCount(getCount() + 1);
}
  • 메소드 호출 부에 Synchronized Block을 통해 감싼다.
@Override
public void run() {
    while (count < maxCount) {
        count++;
        synchronized(sharedCount){
            sharedCount.increment();
        }
    }
}

참고

위 코드를 봐서 알겠지만 블럭에서 sychronized 메서드가 자신의 인스턴스를 매개변수로 갖는 것을 알 수 있다. 따라서 임계 구역 또는 공유 자원에 들어갈 때 인스턴스, 오브젝트 단위로 Lock()을 하고 빠져 나올때 Unlock()을 통해 상호배제를 이루어낸다.
또한 자바에서는 Monitor 방식으로 sychronized가 구현되고있다.

2. 용어정리

  • Critical Section(임계구역) : 공유 자원
  • Mutual Exclusion(상호배제) : Race Condition을 해결하기 위해 공유 자원 접근을 하나의 process, thread로 제한 하는 것(Synchronized)
  • Race Condition(경쟁조건) : 둘 이상의 Thread가 동시에 공유 자원 접근시 발생하는 현상
profile
백엔드개발자

0개의 댓글