You can make anything
by writing

C.S.Lewis

by 강관우 May 03. 2020

[읽고서] 자바 고유락과 온라인 카지노 게임hronization

기술 블로그 리뷰


Java는 크게 3가지 영역의 메모리 영역을 가지고 있습니다.


static 영역

Java 클래스 파일은 크게 필드(field), 생성자(constructor), 메소드(method)로 구성됩니다. 그중 필드 부분에서 선언된 변수(전역 변수)와 정적 멤버변수(static이 붙은 자료형)은 static 영역에서 관리됩니다.


stack 영역

스레드마다 할당받는 영역으로 메소드 내에서 정의하는 기본형 지역 변수와 메소드들의 콜스택을 저장하는 영역입니다.


heap 영역

참조형 데이터 타입을 갖는 객체(인스턴스), 배열 등을 저장하는 영역입니다.


자바 멀티 스레드 환경에서는 스레드들끼리 static 영역과 heap 영역을 공유합니다. 때문에 공유 자원에 대한 동기화 문제를 신경 써야 하는데요, 오늘의 기술 아티클 리뷰는 동기화 문제에 대한 솔루션 중 하나인 Synchronization에 대한 궁금증에서 출발했습니다.


https://www.logicbig.com/tutorials/core-java-tutorial/java-multi-threading/java-intrinsic-locks.html

logicbig이라는 개발 튜토리얼을 모아놓은 사이트입니다.


Intrinstic lock과 온라인 카지노 게임hronized 블록


자바의 모든 객체는 락(lock)을 가지고 있다고 합니다. 모든 객체가 갖고 있으니 고유락(intrinsic lock)이라고한다는데요, 처음에는 이게 뭐지? 싶었는데. 온라인 카지노 게임hronized 블록이 이 고유락을 사용해서 락을 다룬다고 하니 이해가 됐습니다.


자바의 모든 객체(인스턴스, 클래스)는 락을 가지고 있다. synchronized 블록은 이 락을 다룬다.

온라인 카지노 게임hronized 블록은 객체 단위로 락을 다룬다.


아래 예제를 통해서 고유락을 다루는 온라인 카지노 게임hronized를 확인해볼 수 있습니다.


온라인 카지노 게임예제 코드 1


(온라인 카지노 게임hronized 키워드를 무시하고 생각하면) 온라인 카지노 게임Method 안에 5초 동안 멈추는 코드 때문에 각 스레드의 로그는before call 이 찍힌 후 5초 뒤 after call이 찍힐 것으로 예상할 수 있습니다.


output:


thread1 before call 2020-05-03T17:20:05.493925

thread2 before call 2020-05-03T17:20:05.493920

in the 온라인 카지노 게임 method from thread1 2020-05-03T17:20:05.494494

in the 온라인 카지노 게임 method from thread2 2020-05-03T17:20:10.498293

thread1 after call 2020-05-03T17:20:10.498293

thread2 after call 2020-05-03T17:20:15.500107



하지만 실제 로그는 처음 syncMethod를 실행한 thread1만 5초 안에 모든 로그를 찍고 thread2는 10초 정도 걸렸네요. synchronized 블록이 잘 동작해서 해당 영역이 특정 스레드에서 실행되는 동안 다른 스레드가 접근하지 못하게 막은 것으로 보이죠?


하지만 이 예제만으로는 온라인 카지노 게임honized 블록이 어떤 단위로 락을 가지고 가는지 확인할 수 없습니다.


온라인 카지노 게임예제 코드 2


Output:


thread1 before call 2020-05-03T17:21:42.514032

thread2 before call 2020-05-03T17:21:42.513778

in the 온라인 카지노 게임Method1 from thread1 2020-05-03T17:21:42.514289

in the 온라인 카지노 게임Method2 from thread2 2020-05-03T17:21:47.518675

thread1 after call 2020-05-03T17:21:47.518668

thread2 after call 2020-05-03T17:21:52.519938



반면 이 예제에서는 확실히 알 수 있습니다. thread1, thread2가 서로 다른 메소드를 호출함에도 불구하고 thread1은 5초 만에 끝나고 thread2는 또 10초가 걸렸습니다. 인스턴스 lock을 스레드가 갖고 있기 때문이겠죠?


고유락 재진입


고유락 재진입이란 특성을 통해서도 이 '객체 단위 Lock'을 다시 한번 확인할 수 있습니다. 특정 스레드가 온라인 카지노 게임hronized 블록을 통해서 객체에 대한 lock을 획득했다면 해당 객체에 다른 메소드의 lock도 획득합니다.

온라인 카지노 게임예제 코드 3


만약 고유락 재진입 특성이 없다면,a 메서드와 b 메서드가 서로 상호 호출하거나 공유 자원에 대한 선점이 있다면 데드락이 발생할 가능성이 있겠죠!?



static method 온라인 카지노 게임hronization


인스턴스 생성 없이도 클래스의 메소드를 사용할 수 있는 방법이 있습니다. 바로 static인데요, static 메소드에온라인 카지노 게임hronized 블록이 있다면class 단위로 락을 겁니다. 이 부분에서 객체는 인스턴스 혹은 클래스를 나타낸다는 걸인식할 수 있었는데요, 락의 단위가 따로 놀기 때문에 혼용하여 사용한다면 동기화 이슈가 발생할 수 있겠네요..!


예제 코드 4


Output:


thread2 before call 2020-05-03T17:14:51.126421

in the 온라인 카지노 게임 method from thread2 2020-05-03T17:14:51.126983

thread1 before call 2020-05-03T17:14:51.126665

in the 온라인 카지노 게임 method from thread1 2020-05-03T17:14:51.127132

thread2 after call 2020-05-03T17:14:56.130658

thread1 after call 2020-05-03T17:14:56.130677



TMI

Lock의 단위는 멀티스레드 환경의 성능 측면에서 굉장히 중요한 이슈인데요. 단순히 메소드 단위로 온라인 카지노 게임hronized 블록을 적용시켰을 때 해당 객체 전체에락이 걸린다는 이 개념은 HashTable과 같은 레거시 콜렉션 프레임워크에서 이슈가 됐고ConcorrentHashMap에서 개선됐습니다.


HashTable의 Put 메소드 일부, 메소드 전체에 synchronized 블록이 걸려있다. 멀티 스레드 환경에서 put이 실행될 때 해시 충돌이 발생하면 해시 충돌을 해결하기 위한 코드가 성능 이슈를 발생시킨다.


ConcurrentHashMap의 put 메소드는 해쉬 충돌이 발생했을 때 해시 충돌 발생 노드에 대해서만 lock을 획득한다. 다른 노드들에 접근하는 스레드들은 blocking이 발생하지 않으므로 성능 이슈가 개선된다.


브런치는 최신 브라우저에 최적화 되어있습니다.