반응형
개요
- 김영한 강사님의 강의를 듣고 정리하였다.
본론
synchronized 키워드를 이용한 락은 편리하게 임계 영역을 보호할 수 있지만 다음의 문제가 존재한다.
- 임계 영역에서 락을 획득하길 기다리는 스레드들은 BLOCKED 상태에 들어가서 락을 획득할 때까지 대기한다. 이때, 타임아웃 혹은 인터럽트가 불가능하다.
- 임계 영역에서 락을 획득할 때 스레드들은 공정하게 락을 획득하지 못하고 우리는 어떤 스레드가 락을 획득하는지 알 수 없다.
자바 1.5버전부터는 유연하게 임계 영역을 보호하기 위해 java.util.concurrent 패키지가 추가되었다.
이 패키지의 LockSupport 클래스를 알아보자.
LockSupport의 주요 기능
- park() : 스레드를 WAITING 상태로 변경한다.
- synchronized와는 다르게 WAITING 상태로 전환되면서 대기한다.
- parkNanos(nanos) : 스레드를 지정된 나노초 만큼 TIMED_WAITING 상태로 변경한다.
- 지정된 시간이 지나고 나면 RUNNABLE 상태로 전환된다.
- unpark(thread) : 지정된 스레드를 WAITING 상태에서 RUNNABLE 상태로 전환한다.
park()와 unpark(thread)
package thread.start.lock;
import java.util.concurrent.locks.LockSupport;
import static thread.start.util.MyLogger.log;
import static thread.start.util.ThreadUtils.sleep;
public class LockSupportMainV1 {
public static void main(String[] args) {
Thread thread1 = new Thread(new ParkTask(), "Thread-1");
thread1.start();
sleep(100);
System.out.println("Thread-1 state : " + thread1.getState());
LockSupport.unpark(thread1);
}
static class ParkTask implements Runnable{
@Override
public void run() {
LockSupport.park();
}
}
}
- thread-1 스레드는 LockSupport.park()를 호출하여 WAITING 상태로 진입한다.
- 메인 스레드는 0.1초 대기 후 thread-1의 상태를 확인한다. 이때 상태는 WAITING 상태이다.
- 메인 스레드는 LockSupport.unpark(thread1)을 호출하여 thread-1의 상태를 WAITING 상태에서 RUNNABLE 상태로 전환한다.
인터럽트
//LockSupport.unpark(thread1);
thread1.interrupt();
이때, thread-1의 상태는 WAITING이기 때문에 인터럽트를 통해 thread-1을 RUNNABLE 상태로 전환시킬 수도 있다.
- synchronized의 BLOCKED 상태는 인터럽트가 불가능했다!
parkNanos(nanos)
@Override
public void run() {
LockSupport.parkNanos(2000_000000);
System.out.println("state : " + Thread.currentThread().getState());
}
- parkNanos()는 지정된 나노초 만큼 TIMED_WAITING 상태로 진입한 후 지정된 시간 이후에 RUNNABLE 상태로 돌아온다.
- 따라서 2초가 지난 후 스레드는 RUNNABLE 상태가 된다.
결론
LockSupport는 스레드를 BLOCKED 상태로 전환하지 않으면서 임계 영역을 보호할 수 있다.
- synchronized의 인터럽트, 시간 제한 없는 대기 문제를 해결할 수 있다.
하지만 LockSupport만 가지고 실제 락 기능을 구현하기에는 어렵다.
자바는 Lock 인터페이스와 ReentrantLock 구현체를 제공하는데 이는, LockSupport를 사용한 락 기능을 쉽게 사용할 수 있도록 자바가 제공해주는 기능들이다.
반응형
'JAVA' 카테고리의 다른 글
[JAVA] 생산자 소비자 문제와 자바의 Object.wait() notify() (2) | 2024.10.02 |
---|---|
[JAVA] ReentrantLock이 뭔가요? (0) | 2024.09.24 |
[JAVA] 자바의 임계 영역과 동기화, synchronized (0) | 2024.09.23 |
[JAVA] 자바의 volatile 키워드와 메모리 가시성 (1) | 2024.09.23 |
[JAVA] 스레드의 양보 Thread.yield() (0) | 2024.09.21 |