실행과 대기를 반복하며 run() 메서드를 수행한다.
run() 메서드가 종료되면 실행이 멈추게 된다.
상태 | Enum | 설명 |
---|---|---|
객체생성 | NEW | 쓰레드 객체 생성, 아직 start() 메서드 호출 전의 상태 |
실행대기 | RUNNABLE | 실행 상태로 언제든지 갈 수 있는 상태 |
일시정지 | WAITING | 다른 쓰레드가 통지(notify) 할 때까지 기다리는 상태 |
일시정지 | TIMED_WAITING | 주어진 시간 동안 기다리는 상태 |
일시정지 | BLOCKED | 사용하고자 하는 객체의 Lock이 풀릴 때까지 기다리는 상태 |
종료 | TERMINATED | 쓰레드의 작업이 종료된 상태 |
쓰레드는 일시정지 상태를 만들 수 있다.
일시정지된 쓰레드는 실행을 할 수 없는 상태가 된다.
일시정지된 쓰레드를 다시 실행하려면 일시정지상태에서 실행대기 상태로 넘어가야한다.
public static void main(String[] args) {
Runnable task = () -> {
try {
// (1) 예외처리 필수
// - interrupt() 를 만나면 다시 실행되기 때문에
// - InterruptException이 발생할 수 있다.
// (2) 특정 쓰레드 지목 불가
Thread.sleep(2000); // TIMED_WAITTING(주어진 시간동안만 기다리는 상태)
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task : " + Thread.currentThread().getName());
};
Thread thread = new Thread(task, "Thread");
thread.start(); // NEW -> RUNNABLE
try {
// 1초가 지나고 나면 runnable 상태로 변하여 다시 실행
// 특정 스레드를 지목해서 멈추게 하는 것은 불가능
// Static member 'java.lang.Thread.sleep(long)' accessed via instance reference
// 변수 thread를 지칭해서 sleep을 해도 의미가 없다고 나온다.
thread.sleep(1000);
System.out.println("sleep(1000) : " + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
sleep으로 특정 쓰레드를 지목해서 멈추게 하는 것은 불가능하다.
public static void main(String[] args) {
Runnable task = () -> {
// 쓰레드 상태 체크 interrupt 되기 전엔 계속 실행 한다.
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("도달했다.");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("task : " + Thread.currentThread().getName());
};
Thread thread = new Thread(task, "Thread");
thread.start();
thread.interrupt();
System.out.println("thread.isInterrupted() = " + thread.isInterrupted());
}
public static void main(String[] args) {
Runnable task = () -> {
try {
Thread.sleep(5000); // 5초
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(task, "thread");
thread.start();
long start = System.currentTimeMillis();
try {
// 시간을 지정하지 않았기 때문에 thread가 작업을 끝낼 때까지 main 쓰레드는 대기 하게 된다.
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// thread 의 소요시간인 5000ms 동안 main 쓰레드가 기다렸기 때문에 5000이상이 출력됩니다.
System.out.println("소요시간 = " + (System.currentTimeMillis() - start));
}
public static void main(String[] args) {
Runnable task = () -> {
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
}
} catch (InterruptedException e) {
// 남은 시간을 다음 쓰레드에게 양보하고 본쓰레드는 실행대기 상태가 된다.
Thread.yield();
// e.printStackTrace();
}
};
Thread thread1 = new Thread(task, "thread1");
Thread thread2 = new Thread(task, "thread2");
thread1.start();
thread2.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread1.interrupt();
}