LockSupport 에 대해서 자세하게 알아보자 ( 어떻게 무한대기를 없애는지 ).
==> 우선, park / parknanos 메서드부터 알아보자.
package thread.sync.lock;
import java.util.concurrent.locks.LockSupport;
import static util.MyLogger.log;
import static util.ThreadUtils.sleep;
public class LockSupportMainV1 {
public static void main(String[] args) {
Thread thread1 = new Thread(new ParkTest(), "Thread-1");
thread1.start();
// ==> park 상태여서 잠시 대기 상태...
sleep(100);
log("Thread-1 state : " + thread1.getState());
}
static class ParkTest implements Runnable{
@Override
public void run() {
log("park 시작");
LockSupport.park(); // => Runnable -> Waiting 으로 변경
log("park 종료, 상태 : " + Thread.currentThread().getState());
log("인터럽트 상태 : " + Thread.currentThread().isInterrupted());
}
}
}
LockSupport.park() 메서드를 사용해줌
==> Thread1 을 통해서 작업을 진행중임
==> LockSupport.park() 코드를 읽는순간, Runnable -> Waiting 상태로 스레드 상태를 변경
====> 작업을 진행하던 도중에 멈춤
그래서 실행결과를 확인해보면 ...
/Users/hoon/Library/Java/JavaVirtualMachines/openjdk-23.0.1/Contents/Home/bin/java -javaagent:/Users/hoon/Desktop/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=49677:/Users/hoon/Desktop/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath /Users/hoon/Desktop/java/java-adv1/out/production/java-adv1 thread.sync.lock.LockSupportMainV1
16:40:09.694 [ Thread-1] park 시작
16:40:09.789 [ main] Thread-1 state : WAITING
이 상태에서 멈춰있는 상태가 됨.
그럼, 멈춘다음에 작업을 다시 실행하고싶으면 ? ==> unpark() 를 사용 ㄱㄱ
아래에 있는 두줄의 코드를 추가.
log("main 스레드가, Thread-1 의 waiting 상태를 깨우는 ... => 다시 작업할 수 있게");
LockSupport.unpark(thread1);
==================
package thread.sync.lock;
import java.util.concurrent.locks.LockSupport;
import static util.MyLogger.log;
import static util.ThreadUtils.sleep;
public class LockSupportMainV1 {
public static void main(String[] args) {
Thread thread1 = new Thread(new ParkTest(), "Thread-1");
thread1.start();
// ==> park 상태여서 잠시 대기 상태...
sleep(100);
log("Thread-1 state : " + thread1.getState());
log("main 스레드가, Thread-1 의 waiting 상태를 깨우는 ... => 다시 작업할 수 있게");
LockSupport.unpark(thread1); // thread1 -> park 깨우셈
}
static class ParkTest implements Runnable{
@Override
public void run() {
log("park 시작");
LockSupport.park(); // => Runnable -> Waiting 으로 변경
log("park 종료, 상태 : " + Thread.currentThread().getState());
log("인터럽트 상태 : " + Thread.currentThread().isInterrupted());
}
}
}
==> run 에 대한 부분은 Thread-1 스레드가 실행하게될거고,
작업을 맡긴다음에 main 스레드는 밑에 쭉쭉 이어나감
==> main 스레드가, LockSupport.unpark(thread1) 코드를 만나게 되는순간,
thread1 변수로 선언한 Thread-1 스레드가 작업을 다시 진행 ( park 를통해서 바꿔놨던 Waiting 상태 => Runnable )
이런식으로, 스레드에서의 작업을 Waiting 상태로 둘수있고, 풀수도있음 ( park, unpark )
==========
이런식으로 일일이 unpark 를 통해서 깨워주지않고, 특정 시간이 지나면 깨어날수있게 할수있음
==> parkNanos ...
package thread.sync.lock;
import java.util.concurrent.locks.LockSupport;
import static util.MyLogger.log;
import static util.ThreadUtils.sleep;
public class LockSupportMainV3 {
public static void main(String[] args) {
Thread thread1 = new Thread(new ParkTest(), "Thread-1");
thread1.start();
// ==> park 상태여서 잠시 대기 상태...
sleep(100);
log("Thread-1 state : " + thread1.getState());
}
static class ParkTest implements Runnable{
@Override
public void run() {
log("park 시작");
LockSupport.parkNanos(2000_000000); //
log("park 종료, 상태 : " + Thread.currentThread().getState());
log("인터럽트 상태 : " + Thread.currentThread().isInterrupted());
}
}
}
나노 초 단위로 작성해서, 넘겨준 파라미터의 시간만큼 지나게되면 자동으로 Runnable ..