Java Adv 07 - LockSupport

LockSupport

Synchronized의 단점

synchronized는 자바 1.0부터 제공되는 매우 편리한 기능이다. 그러나 몇 가지 단점이 있다.

  1. 무한 대기
    • BLOCKED 상태의 스레드는 락이 풀릴 때까지 무한히 대기하게 된다.
    • 특정 시간까지만 대기하는 타임아웃이 없으며, 중간에 인터럽트가 불가능하다.
  2. 공정성
    • 락이 풀릴 때 BLOCKED 상태의 여러 스레드 중 어떤 스레드가 락을 획득할지 알 수 없다.
    • 최악의 경우 특정 스레드가 매우 오랜 시간 동안 락을 획득하지 못할 수 있다.

이러한 문제를 해결하기 위해 자바 1.5부터 java.util.concurrent 패키지가 추가되었다. 이 패키지는 다양한 동시성 문제를 해결할 수 있는 클래스들을 포함하고 있다.

LockSupport

LockSupportsynchronized의 가장 큰 단점인 무한 대기 문제를 해결할 수 있는 도구이다.

주요 기능

  • 스레드 상태 변경 LockSupport는 스레드를 WAITING 상태로 변경한다. WAITING 상태의 스레드는 누군가가 깨워주기 전까지 대기하며, CPU 실행 스케줄링에 들어가지 않는다.
    1. park()
    • 스레드를 WAITING 상태로 변경한다 (주차하다, 두다의 의미)
      1. parkNanos(nanos)
    • 스레드를 지정한 나노초 동안만 TIMED_WAITING 상태로 변경한다.
    • 지정한 시간이 지나면 TIMED_WAITING 상태에서 빠져나와 RUNNABLE 상태로 변경된다.
      1. unpark(thread)
    • WAITING 상태의 대상 스레드를 RUNNABLE 상태로 변경한다.

이러한 기능들을 통해 LockSupport는 더 유연하고 세밀한 스레드 제어를 가능하게 한다.

Thread Park

image image 재밌는 점은 대기 상태로 바꾸는 LockSupport.park() 는 매개변수가 없는데, 실행 가능 상태로 바꾸는 LockSupport.unpark(thread1) 는 왜 특정 스레드를 지정하는 매개변수가 있을까? 왜냐하면 실행 중인 스레드는 LockSupport.park() 를 호출해서 스스로 대기 상태에 빠질 수 있지만, 대기 상태의 스레드는 자신의 코드를 실행할 수 없기 때문이다. 따라서 외부 스레드의 도움을 받아야 깨어날 수 있다.

시간 대기

image

parkNanos(nanos) : 스레드를 나노초 동안만 TIMED_WAITING 상태로 변경한다. 지정한 나노초가 지나면 TIMED_WAITING상태에서 빠져나와서 RUNNABLE 상태로 변경된다. 참고로 밀리초 동안만 대기하는 메서드는 없다. parkUntil(밀리초) 라는 메서드가 있는데, 이 메서드는 특정 에포크(Epoch) 시간에 맞추어 깨어나는 메서드이다. 정확한 미래의 에포크 시점을 지정해야 한다.

image

parkNanos(시간) 를 사용하면 지정한 시간 이후에 스레드가 깨어난다. 1초 = 1000밀리초(ms) 2초 = 2,000,000,000나노초(ns) 2초의 간격으로 thread가 깨어나는 것을 확인할 수 있다.

Reference

김영한님의 자바 강의



© 2022. by taewoo

Powered by taewoo