You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
9️⃣ CAS 락 구현 1
구현 원리
SpinLockMain
✅ 실행 결과 분석
lock 의 초기값은 false이다.
Thread-1과 Thread-2는 동시에 실행된다.
Thread-1 : if (!lock) 에서 락의 사용 여부를 확인한다. lock의 값이 false 이다.
Thread-2 : if (!lock) 에서 락의 사용 여부를 확인한다. lock 의 값이 false 이다.
Thread-1 : lock = true;를 호출해서 락의 값을 변경한다.
Thread-2: lock = true; 를 호출해서 락의 값을 변경한다.
Thread-1, Thread-2 둘 다 break를 통해 while문을 탈출한다.
Thread-1, Thread-2 둘 다 락 획득을 완료하고, 비즈니스 로직을 수행한 다음에 락을 반납한다.
이 둘은 한 번에 하나의 스레드만 실행해야 한다.
따라서 synchronized 또는 Lock 을 사용해서 두 코드를 동기화해서 안전한 임계 영역을 만들어야 한다.
참고로 락을 반납하는 다음 연산은 연산이 하나인 원자적인 연산이다.
따라서 이 부분은 여러 스레드가 함께 실행해도 문제가 발생하지 않는다.
🔟 CAS 락 구현 2
CAS 연산을 지원하는 AtomicBoolean을 사용했다.
구현 원리
lock의 값이true가 된다.lock의 값이false가 된다.락을 획득할 때 매우 중요한 부분이 있다. 바로 다음 두 연산을 하나로 만들어야 한다는 점이다.
락을 획득하기 위해 먼저 락의 사용 여부를 확인했을 때 lock 의 현재 값이 반드시 false 여야 한다. true 는 이미 다른 스레드가 락을 획득했다는 뜻이다.
따라서 이 값이 false 일 때만 락의 값을 변경할 수 있다.락의 값이 false 인 것을 확인한 시점부터 lock 의 값을 true로 변경할 때 까지 lock 의 값은 반드시 false 를 유지해야 한다.
중간에 다른 스레드가 lock 의 값을 true로 변경하면 안된다. 그러면 여러 스레드가 임계 영역을 통과하는 동시성 문제가 발생한다.
CAS 연산은 두 연산을 하나의 원자적인 연산으로 만들어준다.
lock.compareAndSet(false, true)
SpinLockMain - 코드 변경
SpinLockBad 대신에 SpinLock 을 사용하도록 코드를 변경하자.
참고로 예제를 단순화 하려고 인터페이스는 사용하지 않았다.
실행 결과
실행 결과 분석
서 변경을 시도한다.
Thread-2:while (!lock.compareAndSet(false, true))를 사용해서 락의 사용 여부를 확인하면
서 변경을 시도한다.
Thread-1 : 비즈니스 로직을 수행하고 lock.set(false) 을 수행해서 락을 반납한다.
Thread-2 : 락을 획득하고 while문을 탈출한다. 비즈니스 로직을 수행한 다음에 락을 반납한다.
원자적인 연산은 스레드 입장에서 쪼갤 수 없는 하나의 연산이다. 따라서 여러 스레드가 동시에 실행해도 안전하다.
이렇게 CAS를 사용해서 원자적인 연산을 만든 덕분에 무거운 동기화 작업 없이 아주 가벼운 락을 만들 수 있었다.
동기화 락을 사용하는 경우 스레드가 락을 획득하지 못하면 BLOCKED , WAITING 등으로 상태가 변한다. 그리고 또 대기 상태의 스레드를 깨워야 하는 무겁고 복잡한 과정이 추가로 들어간다. 따라서 성능이 상대적으로 느릴 수 있다.
반면에 CAS를 활용한 락 방식은 사실 락이 없다. 단순히 while문을 반복할 뿐이다. 따라서 대기하는 스레드도 RUNNABLE상태를 유지하면서 가볍고 빠르게 작동할 수 있다.
✅ CAS 단점
✅ 스핀 락
Beta Was this translation helpful? Give feedback.
All reactions