병렬 프로그래밍에서 Thread의 성능 향상을 위해 가능한 블록되거나 컨텍스트 스위칭 되지 않도록 애쓴다. Lock-Free 알고리즘 같은 것들은 이런 노력의 일환이다.
그러나 이런 Lock-Free 알고리즘 같은 것들은 Thread의 활동성을 제한하지 않도록 하다 보니 결합이 발생했을 경우 Spin-Waiting 형태로 구현되는 경향이 있다. 경합이 많거나 구간이 큰 경우는 CPU의 낭비를 가져오는 요인이 된다.
그래서 현실적으로는 일정조건 동안의 Spin-Waiting후에는 스레드를 블록시키는, 즉 잠재우는 형태로 알고리즘을 만든다.
기존의 Java에서는 synchronizd도구 없이는 Thread를 임의로 블록시키고 다시 재기동 시킬만한 도구가 없었다.
따라서 synchronized 없이 Lock-Free하게 구현하는 알고리즘에서 특정 조건에 따라 스레드를 블록시키는 것이 마땅치 않았음.
가능한 스레드가 블록되지 않도록 알고리즘을 작성하다가, 더이상 CPU를 낭비하지 않도록 스레드를 잠재우는 것이 필요한 경우에 해당 스레드가 LockSupport.park를 호출하면 그 스레드를 블록된다. 그 후 다른 스레드가 앞서 블록된 스레드에 대해 LockSupport.unpark를 호출한다.
1. 해당 스레드가 park를 호출했고, 이후에 다른 스레드가 unpark를 호출해 준 경우
2. 다른 스레드가 먼저 unpark를 호출한 후에 해당 스레드가 park를 호출한 경우
unpark할 때 permition이 세팅되었으므로 park를 호출하더라도 잠들지 않고 바로 진행함.
3. 다른 스레드가 먼저 여러번 unpark를 호출할 후에 해당 스레드가 park를 호출한 경우
unpark를 여러번 호출되더라도 Permit은 1번만 세팅되므로, 처음 park를 호출했을 때는 잠들지 않고 바로 진행하게 되지만 이후 다시 park 호출시에는 블록되게 된다.
Basic thread blocking primitives for creating locks and other synchronization classes.
Methods park and unpark provide efficient means of blocking and unblocking threads that do not encounter the problems that cause the deprecated methods Thread.suspend and Thread.resume to be unusable for such purposes: Races between one thread invoking park and another thread trying to unpark it will preserve liveness, due to the permit. Additionally, park will return if the caller's thread was interrupted, and timeout versions are supported. The park method may also return at any other time, for "no reason", so in general must be invoked within a loop that rechecks conditions upon return. In this sense park serves as an optimization of a "busy wait" that does not waste as much time spinning, but must be paired with an unpark to be effective.
docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/LockSupport.html
'개발 > 스프링' 카테고리의 다른 글
web-flux란 (0) | 2021.05.14 |
---|---|
CountDownLatch란 (0) | 2021.04.26 |