JAVA Thread synchronized, Semaphore 싱크로나이즈 세마포어 차이

JAVA Thread synchronized, Semaphore 차이


Thread 프로그래밍에서 synchronized블락은 많은 사람들이 알고있지만, Semaphore를 알고 있는 사람은 비교적 드문것 같다. 멀티 Thread 환경에서 synchronized 블락이 있는 경우와 없는 경우 그리고 Semaphore에 대해서 비교하고자 한다.


synchronized, Semaphore 아무것도 없는 경우

멀티 Thread 환경에서 아무 처리도 하지 않는 경우의 예제 이다. Thread 동기화에 대한 아무런 처리가 안되어 있는 소스기 때문에 수행결과는 순서를 보장하지 못하고 무작위로 출력된다.


샘플소스

  • MainClass 는 Thread 를 for문을 통해서 5개 생성하도 바로 실행한다.
  • Thread의 Runnable은 final 객체 SomeResource.use()를 수행한다.
수행결과

USE 시작 : Thread-4

USE 시작 : Thread-0

USE 시작 : Thread-2

USE 시작 : Thread-1

USE 시작 : Thread-3

USE 종료 : Thread-3

USE 종료 : Thread-4

USE 종료 : Thread-1

USE 종료 : Thread-2

USE 종료 : Thread-0


synchronized 처리가 되어있는 경우

위와 소스코드에서 16번째 라인을 아래와 같이 synchronized 블락으로 변경해보자.

15 : class SomeResource {

16 :    public synchronized void use() {


synchronized 블락이 있는 경우 어떤 Thread가 진입하는 순간 다른 Thread의 진입을 막는다. 그래서 변경된 예제를 수행한다면, Thread-1 시작 -> Thread-1 종료, Thread-2 시작 -> Thread-2 종료... 로 하나의 쓰레드가 작업을 완전히 종료 한 뒤에 다른 쓰레드가 작업을 시작하게 된다.


synchronized 수행결과

USE 시작 : Thread-2

USE 종료 : Thread-2

USE 시작 : Thread-4

USE 종료 : Thread-4

USE 시작 : Thread-0

USE 종료 : Thread-0

USE 시작 : Thread-1

USE 종료 : Thread-1

USE 시작 : Thread-3

USE 종료 : Thread-3


예상대로 하나의 Thread가 완전히 작업을 종료된 이후에 다른 Thread가 작업을 시작한다.


Semaphore로 동시접근 Thread 계수제어

synchronized의 경우 오직 하나의 Thread만 수행가능하게 했다면, Semaphore는 동시에 실행할 수 있는 Thread의 수를 제어할 수 있다. 아무처리도 하지 않은 첫 번째 예제를 Semaphore를 적용하여 약간 변경해보았다. 동시에 수행중인 Thread의 숫자를 프린트 하는 샘플이다.


Semaphore샘플


Semaphore수행결과

[Thread-1]1쓰레드가 점유중 // 1번 쓰레드가 사용중

[Thread-0]2쓰레드가 점유중 // 1번, 0번 쓰레드가 사용중

[Thread-2]3쓰레드가 점유중 // 1번, 0번, 2번 쓰레드가 사용중

[Thread-3]3쓰레드가 점유중 

[Thread-9]3쓰레드가 점유중

[Thread-8]3쓰레드가 점유중

[Thread-7]3쓰레드가 점유중

[Thread-5]3쓰레드가 점유중

[Thread-6]3쓰레드가 점유중

[Thread-4]3쓰레드가 점유중


semaphore.acquire(); // Thread 가 semaphore에게 시작을 알림

..... 처리 .....

semaphore.release(); // Thread 가 semaphore에게 종료를 알림


이렇게 Semaphore를 처리하는 경우 동시에 수행되는 Thread의 숫자를 제어하는 것이 가능하다.


Semaphore처리과정


세마포어의 계수가 0보다 큰경우 Thread가 데이터에 접근이 가능하고, 0인 경우는 접근을 차단한다.


Thread는 세마포어에 접근할때(acquire()) 세마포어 계수(permits)를 하나 감소시키고, 작업이 종료되고 나올때 (release()) 세무포어 계수를 다시 1증가 시키게 된다.


위와 같이 간단한 메커니즘으로 Semaphore를 통한 Thread 동시접근을 제어한다.



정리

  • 아무처리 하지 않음 : 다수의 Thread가 접근하여 동기화 문제 발생
  • synchronized 처리 : 오직 하나의 Thread만 접근할 수 있게 함
  • Semaphore 처리 : 사용자가 직접 접근 가능한 Thread의 수를 지정


이 글을 공유하기

댓글

Email by JB FACTORY