일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- 쓰레드
- MAP
- cpu
- 트리
- linkedmap
- 프로그래머스
- black-red
- set
- avl
- 자바
- os 쓰레드
- list
- Red-Black
- 유저모드
- Java
- 코테
- 쓰레드 덤프
- Lock
- 코딩테스트
- OS
- 유저 쓰레드
- non-blocking
- 하드웨어 쓰레드
- 배열
- 스케줄링
- 커널모드
- HashMap
- synchronizeation
- tree
변수의 기록
(CS) 모니터(Monitor)란? (컴퓨터 모니터 아님.) synchronized 본문
(CS) 모니터(Monitor)란? (컴퓨터 모니터 아님.) synchronized
불광동 물주먹 2025. 4. 11. 00:081. 모니터(Monitor)란?
- 정의: 모니터는 **상호배제(Mutual Exclusion)**와 **조건 동기화(Conditional Synchronization)**를 제공하는 고수준 동기화 추상화.
- 주요 구성 요소:
- 뮤텍스 락(Mutex Lock): 임계 구역(Critical Section)에 동시에 하나의 스레드만 들어갈 수 있도록 함.
- 엔트리 큐(Entry Queue): 락을 얻기 위해 대기 중인 스레드들이 대기.
- 컨디션 변수(Condition Variable): 특정 조건을 기다리는 스레드들이 대기하는 공간.
- 웨이팅 큐(Waiting Queue): 컨디션 변수를 통해 조건을 기다리는 스레드들이 들어감.
상황 1 - producer 에서 item을 넣어주고 consumer에서는 꺼내 씀
조건 - 1. buffer 사이즈는 고정
문제점 1. producer 는 buffer에 빈공간이 없어도 계속 확인을 하고 넣어줘야하나?
문제점 2. consumer 에서도 buffer에 빈공간인데 계속 확인을 해가며 꺼내와야하나?
*위 문제를 모니터를 통해 해결 할 수 있다.
조건 1. global Buffer를 두고 공유
조건 2. Buffer 를 사용할때는 Critical Section 안에서 Mutual Exclusion이 보장 될 수 있도록 사용되어야한다.
(보장하지 않으면 레이스 컨디션 발생 가능)
조건 3. global lock 은 뮤텍스 락 (lock 점유 실패시 엔트리 큐에 대기)
상황 1.프로듀서에서 item 삽입하려는데 -> 버퍼가 다 차면 웨이팅 ( 웨이팅 큐 ) -> 작업을 완료한 컨슈머가 깨워줌( 대기 중인 한 쓰레드 웨이팅 큐 탈출) ++ 깨우는 방법은 시그널이나 브로드캐스트로 -> lock 반환(엔트리큐 다음 쓰레드 진행 (순서는 개발자가 만들기 나름))
상황 2. 반대로 컨슈머에서 item 꺼내려는데 -> 버퍼가 비면 웨이팅( 웨이팅 큐 ) -> 작업을 완료한 프로듀서에서 버퍼 채운후 깨워줌 (대기 중인 한 쓰레드 웨이팅 큐 탈출) -> lock 반환(엔트리큐 다음 쓰레드 진행 (순서는 개발자가 만들기 나름))
상황 3. 작업이 끝나면 lock.relesase()로 뮤텍스 락 반환
**컨슈머 혹은 프로듀서 깨운 후 작업 진행 방법 2가지
1) signal & continue : 작업을 완료한 컨슈머가 꺠워준 후 작업 이어서 마저 한후 lock 반환
2) signal & wait : 작업을 완료한 컨슈머가 꺠워준 후 깨운 쓰레드가 작업 새로 시작하고 작업 마친 후 이후 락 반환 후 컨슈머 작업 재개 (컨슈머 작업 재개는 엔트리락에서 대기 후 자기 차례가 오면 진행)
*wait문은 반드시 while 문 안에서 실행되어야한다. (내가 기다렸던 조건이 충족되는지 다시 확인해야함!!)
2. Java에서의 모니터 구현
- 모든 Object는 내부적으로 모니터를 갖는다.
- synchronized 블록/메서드: 락 + 모니터 기능
- 단일 컨디션 변수 제공 (wait, notify, notifyAll)
📌 synchronized 키워드 ( Mutual Exclusion 보장)
- 객체의 모니터 락을 획득해야 진입 가능.
- 락을 못 얻은 스레드는 엔트리 큐에서 대기.
📌 wait(), notify(), notifyAll()
- wait(): 현재 스레드는 웨이팅 큐로 이동하여 대기 (락을 반납함).
- notify(): 웨이팅 큐에서 하나의 스레드를 깨움.
- notifyAll(): 웨이팅 큐에 있는 모든 스레드를 깨움.
⚠️ 반드시 wait/notify는 synchronized 블록 내부에서 호출되어야 함.
#java
synchronized(obj) {
while (조건 안맞음) {
obj.wait();
}
// 조건 맞음 - 작업 수행
}
3. 여러 개의 조건 변수 필요 시 (Java 기준)
- java.util.concurrent.locks.Condition 사용
- ReentrantLock과 함께 사용
- 하나의 Lock 객체에 여러 Condition 객체 생성 가능 (자바 기본 모니터와 차이점)
📌 예시 코드:
#java
Lock lock = new ReentrantLock();
Condition condA = lock.newCondition();
Condition condB = lock.newCondition();
lock.lock();
try {
while (!조건A) {
condA.await(); // wait
} // 작업 수행
condB.signal(); // 특정 조건에 대해 신호
} finally {
lock.unlock();
}
4. 자바 동기화 관련 주요 클래스 (java.util.concurrent)
분류 | 클래스 | 설명 |
락 | ReentrantLock | 재진입 가능한 락, synchronized 대체 |
락 | ReadWriteLock | 읽기/쓰기 락 분리 |
락 | StampedLock | 낙관적 읽기 지원 (성능 개선) |
조건 변수 | Condition | ReentrantLock과 함께 사용, 복수 조건 관리 |
동기화 큐 | BlockingQueue, LinkedBlockingQueue | Producer-Consumer 패턴에 사용 |
동기화 도구 | Semaphore | 지정된 수만큼의 동시 접근 허용 |
동기화 도구 | CountDownLatch | 특정 이벤트가 끝날 때까지 대기 |
동기화 도구 | CyclicBarrier | 지정된 수의 스레드가 모두 도달할 때까지 대기 |
동기화 도구 | Phaser | 단계적으로 동기화, CyclicBarrier 개선판 |
동기 변수 | AtomicInteger, AtomicBoolean | 원자성 보장 변수들 (CAS 기반) |
정리 요약
- 모니터 = 락 + 컨디션 변수
- Java의 synchronized는 하나의 기본 컨디션 변수 내장 (wait/notify)
- 여러 컨디션 필요 → ReentrantLock + Condition
- wait()는 항상 while로 조건을 확인해야 함 (스퍼리어스 웨이크업 방지)
- 고성능, 유연한 동기화 → java.util.concurrent 사용 권장
'CS지식 > 운영체제 (Operating System)' 카테고리의 다른 글
(OS) 자바 스레드의 상태 – OS 프로세스 상태 비교 (0) | 2025.04.13 |
---|---|
(OS) 데드락이란? (발생조건 , 해결방안 포함) (0) | 2025.04.12 |
(CS 운영체제) 동기화 (기본) (0) | 2025.04.07 |
(CS 운영체제) 동시성 - 스핀락(spinlock) 뮤텍스(mutex) 세마포(semaphore) 각각 특징과 차이 설명 java (0) | 2025.04.07 |
(CS 운영체제)CPU-bound vs IO-bound :시스템 최적화를 위한 성능 특성 및 쓰레드 전략 정리 (0) | 2025.04.06 |