스레드는 여러 개 생성할 수 있으나, 실행 시에는 각 스레드가 순차적으로 처리되어야 하기 때문에 한 번에 하나씩 대기열을 따라 실행된다.
new를 사용해 스레드를 생성하면, 즉시 실행되는 것이 아니라 이미 진행 중인 스레드나 다른 스레드의 영향으로 Runnable이라는 대기열에 들어간다. 이후 이전 스레드가 할당된 시간을 모두 소진하거나 종료되면, 대기 중이던 스레드가 실행을 시작한다.
package thread;
public class wait {
public static void main(String[] args) {
Thread th = Thread.currentThread();
th.setName("Main");
Runnable subMain = new Runnable() {
@Override
public void run() {
System.out.printf(" %s : %s\n", th.getName(), th.getState());
print();
System.out.printf(" %s : %s\n", th.getName(), th.getState());
}
};
Thread th1 = new Thread(subMain);
th1.setName("sub1");
System.out.printf(" %s : %s\n", th1.getName(), th1.getState()); // 시작전 상태 출력
th1.start();
System.out.printf(" %s : %s\n", th1.getName(), th1.getState()); // 시작후 상탱 출력
System.out.printf(" %s : %s\n", th1.getName(), th1.getState());
System.out.printf(" %s : %s\n", th1.getName(), th1.getState());
System.out.printf(" %s : %s\n", th1.getName(), th1.getState());
System.out.printf(" %s : %s\n", th1.getName(), th1.getState());
if(th1.isAlive())
try {
th1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("============ Main Exit ================="); // main 끝남
}
public static void print() {
Thread th = Thread.currentThread();
for(int i=0; i<100; i++) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if( th.getName().equals("Main")){
System.out.printf("<%s[%d]:%d>\n", th.getName(), th.getId(), i+1);
}
else {
System.out.printf("%s[%d]:%d\n", th.getName(), th.getId(), i+1);
}
}
}
}
sleep 메소드를 사용하게 되면, 해당 스레드는 지정된 시간 동안 일시 정지 상태에 들어가고, 그 시간이 지난 후 대기열에 들어가 다시 실행을 준비하게 된다.
thread의 상태가 정상적으로 출력됨