import thread.start.HelloRunnable;
import static util.MyLogger.log;
public class ThreadInfoMain {
public static void main(String[] args) {
// main 스레드
Thread mainThread = Thread.currentThread();
log("mainThread = " + mainThread);
log("mainThread.threadId()=" + mainThread.threadId());
log("mainThread.getName()=" + mainThread.getName());
log("mainThread.getPriority()=" + mainThread.getPriority());
log("mainThread.getThreadGroup()=" + mainThread.getThreadGroup());
log("mainThread.getState()=" + mainThread.getState());
// myThread 스레드
Thread myThread = new Thread(new HelloRunnable(), "myThread");
log("myThread = " + myThread);
log("myThread.threadId()=" + myThread.threadId());
log("myThread.getName()=" + myThread.getName());
log("myThread.getPriority()=" + myThread.getPriority());
log("myThread.getThreadGroup()=" + myThread.getThreadGroup());
log("myThread.getState()=" + myThread.getState());
}
}
출력 👇
18:35:15.649 [ main] mainThread = Thread[#1,main,5,main]
18:35:15.652 [ main] mainThread.threadId()=1
18:35:15.652 [ main] mainThread.getName()=main
18:35:15.654 [ main] mainThread.getPriority()=5
18:35:15.654 [ main] mainThread.getThreadGroup()=java.lang.ThreadGroup[name=main,maxpri=10]
18:35:15.654 [ main] mainThread.getState()=RUNNABLE
18:35:15.654 [ main] myThread = Thread[#22,myThread,5,main]
18:35:15.654 [ main] myThread.threadId()=22
18:35:15.654 [ main] myThread.getName()=myThread
18:35:15.655 [ main] myThread.getPriority()=5
18:35:15.655 [ main] myThread.getThreadGroup()=java.lang.ThreadGroup[name=main,maxpri=10]
18:35:15.655 [ main] myThread.getState()=NEW
여기서 getState()을 보면 mainThread는 RUNNABLE,
myThread는 NEW라는걸 볼 수 있다.
NEW는 간단히 말해서 생성되었지만 동작을 안하는 상태라고 보면 되는데 좀 더 자세히 알아보자.
myThread 라는 이름을 지정해줘서 이 값이 반환된 것이다.setPriority()를 통해 지정할 수 있다.Thread.State 열거형에 정의된 상수 중 하나다.
실제로 자바에서 스레드 일시 중지 상태(Suspended Stated)라는 상태는 없지만, 스레드가 기다리는 상태들을 묶어서 쉽게 이해하기 위해 사용할 예정!
Thread 객체가 생성되지만, start() 메서드가 호출되지 않은 상태Thread thread = new Thread(runnable);start() 메서드가 호출되면 스레드는 Runnable 상태로 들어간다.thread.start();Runnable 상태의 모든 스레드가 동시에 실행되는 것은 아니고 스케줄러에 따라 대기열에 있다가 순서대로 CPU에서 실행된다.참고) 궁금해서 Chat GPT 한테 물어봤다.
Q. 그럼 스케줄러 대기열에 들어가는 Thread는 모두 Runnable 상태여야 하는건가?
A. 운영체제 스케줄러에 의해 실행 후보가 되는 스레드는 기본적으로 “Runnable” 상태여야 한다. 따라서, 운영체제(OS) 입장에서는 Runnable 상태만이 “스케줄링 대상”이 된다.
synchronized 블록에 진입하기 위해 락을 얻어야 하는 경우 이 상태에 들어간다.lock을 가지고 있는 경우 해당 스레드는 BLOCKED 상태가 된다.synchronized (lock) {...}wait(), join() 메서드가 호출될 때 이 상태가 된다.notify() or notifyAll() 메서드를 호출하거나, join() 이 완료될 때까지 기다린다.object.wait();sleep(long millis), wait(long timeout), join(long millis) 메서드가 호출될 때 이 상태가 된다.Thread.sleep(1000);run() 메서드가 완료되면 TERMINATED 상태가 된다.참고)
Thread.currentThread().getState()와 스레드 객체인thread.getState()의 차이
Thread.currentThread().getState()해당 코드를 실행하는 스레드 객체에 대한 state를 보여주고, 스레드 객체인thread.getState()는 생성한 스레드 객체에 대한 상태를 볼 수 있다.
차이를 분명하게 이해하길!
예) 현재 main 스레드의 코드 구간에서 보고 있는데 상태를 찍어봤다면,
Thread.currentThread().getState()> main 스레드의 상태
스레드 객체인thread.getState()는 main 스레드에서 만들어진 스레드 객체의 상태.