- 데이터를 concurent하게 처리하면서 공유되는 데이터에 동시에 접근하게 되는데 이때, 데이터의 불일치가 나타날 수 있다.
=> 이를 해결하기 위해서 실행 순서를 정해 배타적으로 접근하는 것이 필요하다.
- Producer-Consumer Problem에서 Producer는 counter++을 하고 Consumer는 counter--를 하여 동시에 counter에 접근하여 값을 변경시킬 수 있는데 이때 데이터의 불일치가 나타난다

counter++의 동작

counter--의 동작

동시에 일어났을 때의 데이터 불일치 문제
=> 연산의 원자성이 보장되지 않기 때문에 생김
critical section: shared data가 존재하는 코드 부분
critical section problem: 여러 프로세스 또는 스레드가 shared data에 동시에 접근하는 상황에서의 동기화 문제
- 다음 세가지를 만족함으로써 Critical Section문제를 해결할 수 있다.
Mutual Exclusion(상호 배제): 동시에 critical section을 진입할 수 없음
Progress(진행): 필요없는 지연없이 critical section이 비었다면 진입하는 것
Bounded Waiting(한정된 대기): 무한정 대기 하지 않는 것, 진입 요청 사이에 다른 프로세스가 진입하는 횟수에 대한 제한

Peterson's Solution
- 현대 컴퓨터에서는 성능을 위해 코드의 순서가 바뀔 수 있기 때문에 동시에 진입하여 mutual exclusion이 보장되지 않는다.

Peterson's Solution의 순서가 바뀐 예시: cs에 동시에 진입
- 앞에서 봤듯 코드의 현대의 컴퓨터는 순서가 보장되지 않기 때문에 이 순서를 보장해줄 3가지 하드웨어적인 해결방법이 있다.

Memory Barries
- 명령어를 이용하여 명령어 기준 이후의 코드가 이전의 코드보다 나중에 실행되도록 보장
- 하드웨어의 지원으로 원자적으로 실행되도록 하는 lock 명령어들

TAS 코드

TAS를 이용한 Lock

CAS 코드

CAS를 이용한 Lock

Atomic variable

acquire, release 코드

wait와 signal 코드
Counting Semaphore: 모든 범위의 정수를 사용, 여러 프로세스가 접근할 때 유용
Binary Semaphore: 0과1만 사용, mutex lock과 같다.

wait 코드 with no Busy Waiting
- 먼저 value 값을 줄이고 0보다 작으면 waiting queue에 둠(sleep)

signal 코드 with no Busy Waiting
- 먼저 value 값을 늘리고 0 이하이면 waiting queue에서 ready queue로 이동(wakeup)
- 앞의 주의점을 지키지 않고 사용한다면 error가 발생할 수 있기 때문에 이를 관리하기 위해 고급언어에서 지원하는 도구

wait와 signal을 잘못 사용한 예시

Monitor 구조

- 조건변수를 설명하기 위해 producer-consumer를 예시로 들자면
condition x: if count == 0 // 소비자가 먼저 올 때의 조건변수
x.wait() => 소비자가 먼저 진입하여 조건변수에 의해 내부에서 Monitor 내부에서 대기하게 됨
x.signal() => 생산자가 진입하여 내부에서 대기하는 소비자가 있으면 실행되게 함

Monitor의 함수 내부 구현

Monitor의 condition wait와 signal구현
실제로 자바에서는 'Monitor 인터페이스를 상속받아서 오버라이딩 하는건가?' 라는 생각이 들어 추가적으로 찾아보니
실제로는 최상위 클래스인 Object클래스에 synchronized 키워드를 사용하여 내부적으로 모니터 또는 락(lock)을 사용하여 동기화를 구현한다고 한다.
또한, wait(), notify(), notifyAll()과 같은 메서드들을 사용하여 조건 변수를 활용할 수도 있다고 한다. notify는 앞의 signal과 같다.