join() 사용 예시
public class JoinMainV3 {
public static void main(String[] args) throws InterruptedException {
log("Start");
SumTask task1 = new SumTask(1, 50);
SumTask task2 = new SumTask(51, 100);
Thread thread1 = new Thread(task1, "thread-1");
Thread thread2 = new Thread(task2, "thread-2");
thread1.start();
thread2.start();
// 스레드가 종료될 때 까지 대기
log("join() - main 스레드가 thread1, thread2 종료까지 대기");
thread1.join();
thread2.join();
log("main 스레드 대기 완료");
log("task1.result = " + task1.result);
log("task2.result = " + task2.result);
int sumAll = task1.result + task2.result;
log("task1 + task2 = " + sumAll);
log("End");
}
static class SumTask implements Runnable { ... }
}
실행결과
16:46:56.803 [ main] task1.result = 1275
16:46:56.803 [ main] task2.result = 3775
16:46:56.804 [ main] task1 + task2 = 5050 ← 정확하게 출력됨
log("join() 실행"); // main - RUNNABLE
thread1.join(); // main - WAITING
// main - RUNNABLE
thread2.join(); // main - WAITING
WAITING, TIMED_WAITING 같은 대기 상태의 스레드를 직접 깨워서, 작동하는 RUNNABLE 상태로 만들 수 있음
InterruptedException
Thread.sleep()
,wait()
, 또는join()
와 같은 블로킹 메서드가 실행 중일 때, 스레드가 >interrupt 상태로 설정되면 발생- if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
특정 스레드의 인스턴스에 interrupt() 메서드를 호출
→ Thread.sleep() 상태에 있던 스레드에 InterruptedException 발생
→ 이때 인터럽트를 받은 스레드는 대기 상태에서 깨어나 RUNNABLE 상태가 되고 코드 정상 수행
→ InterruptedException을 catch로 잡아서 정상 흐름으로 변경
true
를 반환하고, 해당 스레드의 인터럽트 상태를 false
로 변경false
를 반환하고, 해당 스레드의 인터럽트 상태를 변경하지 않는다.
public class YieldClass {
static final int THREAD_COUNT = 1000;
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
static class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
// 1. empty
// sleep(1); // 2. sleep
// Thread.yield() // 3. yield
}
}
}
}
Empty
: sleep(1)
, yield()
없이 호출한다. 운영체제의 스레드 스케줄링을 따른다.sleep(1)
: 특정 스레드를 잠시 쉬게 한다.yield()
: yield()
를 사용해서 다른 스레드에 실행을 양보한다.