반응형
자바는 stack, heap, static 이라는 3개의 메모리 영역을 가지고 있다. 자바 멀티 스레드 환경은 스레드들끼리 static, heap영역을 공유하기 때문에 공유 자원에 대한 동기화 문제를 신경 써야 한다. 자바는 java.util.concurrent.lock 패키지를 통해 Lock 외의 직접 동기화 구현이 가능한 lock 구현제를 제공하는데, 여기에 Synchronized와 Reentrant 등의 클래스가 존재한다. 이 둘의 차이점은 아래와 같다.
1. synchronized와 Reentrant 차이
1.1. Synchronized
- 현재 데이터를 사용하고 있는 해당 스레드를 제외한 나머지 스레드들이 데이터에 접근 불가하도록 하는 개념
- 자바에서 스레드 동기화 시 사용하는 대표적인 기법
- synchronized 키워드가 붙은 메서드를 사용하려면 lock을 가지고 있어야 한다.
- 단점으로는 synchronized를 너무 많이 남발하면 메서드나 변수 동기화를 위해 block과 unblock이 일어나면서 프로그램의 성능저하가 일어날 수 있다.
1.1.1. 사용법
1. synchronized 키워드를 사용한 메소드 생성
<java />public synchronized void TestSyn(){ 내용 }
메소드에 synchronized 키워드를 사용해 그 메소드가 포함된 해당 객체(this)에 lock을 거는 방법
이 방법을 사용하면, 해당 객체에 포함된 다른 모든 synchronized의 접근까지 Lock이 걸려 좋은 방법은 아니다.
2. statements:synchronized block을 사용
synchronized를 사용해, 해당 블록 안에 내용 부분만 Lock이 걸리도록 사용할 수 있다.
<java />private Object obj = new Object(); public void test(){ synchronized(obj){ 내용 } }
1.2. ReentrantLock
- 특정 statements에 대한 Locking을 관리하는 것을 볼 수 있다.
- synchronized 사용 시 스레드가 어떤 상태인지 확인이 불가해 Lock이 걸리면 Release까지 무한하게 기다릴 수 밖에 없으나 ReentrantLock을 사용하면 현재 상태를 확인할 수 있다.
1.2.1. Reentrant 기능
- lock() : lock 가져오기
- unlock() : lock 해제
- tryLock() : 일정 시간 대기 또는 현재 상태 확인 후 true, false 를 리턴. true인 경우 lock을 얻음
- isHeldByCurrentThread() : 현재 스레드가 lock을 얻었는지 확인
- hasQueuedThreads() : 해당 객체에 lock을 얻기 위해 기다리는 스레드가 있는지 확인
- getOwner() : 지금 lock을 갖고있는 스레드를 리턴
1.2.2. 사용법
reentrantLock객체 생성 후 사용
<java />private final ReentrantLock lock = new ReentrantLock();
1.3. Synchronized와 ReentrantLock의 차이점
- Synchronized는 어느 스레드가 먼저 lock을 획득할지 보장하지 못하나, ReentrantLock락은 가능
- Synchronized는 임계 영역의 시작과 끝이 있어야 하나, Reentrant는 lock, unlock을 사용해 여러 메서드에 나눠 작성이 가능
- 현실적으로 rock, unlock을 여러 메서드에서 쓰는 경우는 거의 없다. 굉장히 위험한 짓이기 때문에..!
1.4. 공정성?
- 락 사용 시 경쟁이 발생하면 가장 오래 기다린 스레드에게 lock을 제공하는 것
- Synchronized는 공정성 지원하지 않지만 Reentant는 지원함
1.5. 참조 블로그
https://velog.io/@may_yun/JAVA-synchronized-VS-Reentrant-Lock-차이점
반응형
'Develop > Java' 카테고리의 다른 글
[Java] Atomic과 CAS(Compare and swap) (0) | 2023.05.29 |
---|---|
[Java] Synchronized 동기화 예제 (0) | 2023.05.14 |
[Java] Thread란? (0) | 2023.05.14 |
[intellij] gradle 다른 프로젝트 참조(클래스 참조방법) (0) | 2023.05.01 |
[IntelliJ] Sub project(Multi Module) 구성 방법 (0) | 2023.04.03 |