티스토리 뷰

Java & Spring

[Java] Thread 동기화하기

강씨아저씨 2016. 2. 1. 21:52

이번에는 자바 멀티스레드 환경에서 동기화하는 법에 대해서 알아보겠다.

예전에 C++ 환경에서 멀티스레드 동기화 자료가 있으니 필요하신분들은 그쪽을 확인하시면 되겠다.

우선 동기화가 필요한 이유는 N개의 스레드가 공통자원을 사용할때 문제가 생기기 때문이다.

 

다음과 같은 코드가 있다고 할때 양쪽 스레드에서 res를 10000번 ++ 증가 시키기 때문에 2개의 쓰레드의 합으로 결과가 20000이 나올것이라 예상했다.



 

하지만 결과를 보면 우리의 예상과는 다르다. 

 

 

이러한 값이 나오는 이유는 예를들어 th1이 res가 100인 값을 증가하려고 할 때 동시에 th2도 res 변수를 증가시키려고 할때가 있다.

 

그러면 사실 두 개의 스레드가 증가시켰으니 102가 되어야 하지만 th1과 th2가 동시에 res변수에 접근했음으로 둘 다 100에 1을 더한 101이 된다. 


이러한 경우 때문에 우리가 예상한 20000이 나오지 않았다!

 

그래서 이러한 N개의 스레드가 동시에 1개의 자원을 접근할때 관리를 해야하므로 동기화가 필요하다. 

 

자바의 동기화하는법은 아주 간단하다. 바로 synchronized!

이 키워드를 이용해서 동기화 영역을 지정하면 된다!

 

이 키워드를 이용하면 어떤 스레드가 동기화된 영역을 먼저 참조하고 있다면 다른 스레드가 접근할 수 없게 한다.

 

synchronized 키워드 괄호 사이에 락 객체를 설정할수도 있지만 여기서는 따로설명하지 않겠다. (락 객체를 설정하면 락 객체마다 동기화가 다르다)

 

다음과 같이 sum()의 함수에 synchronized 키워드를 이용해 동기화를 걸었다.



 

그러면 먼저 sum에 접근한 스레드가 sum함수를 끝내기 전까지 뒤에 도착한 스레드는 대기를 한다!

 

이를 통해서 res가 먼저 10000번 ++ 증가 연산 끝내면 그뒤에 대기하던 스레드도 이어서 res를 10000번 ++ 증가연산을 한다. 

 

결과는 다음과 같다. 

 

 

자바 멀티쓰레드에서의 동기화는 이렇게 하면 되겠다.
 

누군가에게는 작은도움이 되었기를 바라면서 오늘의 포스팅 끝~

댓글