Java Adv 07 - LockSupport
in Programming Language on Java
LockSupport
Synchronized의 단점
synchronized는 자바 1.0부터 제공되는 매우 편리한 기능이다. 그러나 몇 가지 단점이 있다.
- 무한 대기
BLOCKED상태의 스레드는 락이 풀릴 때까지 무한히 대기하게 된다.- 특정 시간까지만 대기하는 타임아웃이 없으며, 중간에 인터럽트가 불가능하다.
- 공정성
- 락이 풀릴 때
BLOCKED상태의 여러 스레드 중 어떤 스레드가 락을 획득할지 알 수 없다. - 최악의 경우 특정 스레드가 매우 오랜 시간 동안 락을 획득하지 못할 수 있다.
- 락이 풀릴 때
이러한 문제를 해결하기 위해 자바 1.5부터 java.util.concurrent 패키지가 추가되었다. 이 패키지는 다양한 동시성 문제를 해결할 수 있는 클래스들을 포함하고 있다.
LockSupport
LockSupport는 synchronized의 가장 큰 단점인 무한 대기 문제를 해결할 수 있는 도구이다.
주요 기능
- 스레드 상태 변경
LockSupport는 스레드를WAITING상태로 변경한다.WAITING상태의 스레드는 누군가가 깨워주기 전까지 대기하며, CPU 실행 스케줄링에 들어가지 않는다.park()
- 스레드를
WAITING상태로 변경한다 (주차하다, 두다의 의미)parkNanos(nanos)
- 스레드를 지정한 나노초 동안만
TIMED_WAITING상태로 변경한다. - 지정한 시간이 지나면
TIMED_WAITING상태에서 빠져나와RUNNABLE상태로 변경된다.unpark(thread)
WAITING상태의 대상 스레드를RUNNABLE상태로 변경한다.
이러한 기능들을 통해 LockSupport는 더 유연하고 세밀한 스레드 제어를 가능하게 한다.
Thread Park
재밌는 점은 대기 상태로 바꾸는
LockSupport.park() 는 매개변수가 없는데, 실행 가능 상태로 바꾸는 LockSupport.unpark(thread1) 는 왜 특정 스레드를 지정하는 매개변수가 있을까? 왜냐하면 실행 중인 스레드는 LockSupport.park() 를 호출해서 스스로 대기 상태에 빠질 수 있지만, 대기 상태의 스레드는 자신의 코드를 실행할 수 없기 때문이다. 따라서 외부 스레드의 도움을 받아야 깨어날 수 있다.
시간 대기
parkNanos(nanos) : 스레드를 나노초 동안만 TIMED_WAITING 상태로 변경한다. 지정한 나노초가 지나면 TIMED_WAITING상태에서 빠져나와서 RUNNABLE 상태로 변경된다. 참고로 밀리초 동안만 대기하는 메서드는 없다. parkUntil(밀리초) 라는 메서드가 있는데, 이 메서드는 특정 에포크(Epoch) 시간에 맞추어 깨어나는 메서드이다. 정확한 미래의 에포크 시점을 지정해야 한다.
parkNanos(시간) 를 사용하면 지정한 시간 이후에 스레드가 깨어난다. 1초 = 1000밀리초(ms) 2초 = 2,000,000,000나노초(ns) 2초의 간격으로 thread가 깨어나는 것을 확인할 수 있다.
Reference
김영한님의 자바 강의