main(){
myThread myThread = new myThread();
myThread.start(); <-- 실행하면 Thread 출력해야댐
System.out.println("Hello "+Thread.currentThread().getName());
}
static class myThread extends Thread {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getName());
}
}
//output
Hello main <-- 근데 hello가 먼저나옴
Thread Thread-0
순서상 Thread가 나오고 Hello가 나올거같지만 간혹 순서가 바뀌어서 나오기도한다 (순서 보장x)
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getName());
}
});
람다식으로 전환
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000L); <-- 1초 대기
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + Thread.currentThread().getName());
}
thread.start();
System.out.println("Hello "+Thread.currentThread().getName()); <-- 대기중인 쓰레드 대신 main쓰레드가 먼저 실행된다 (순서 보장o)
//output
Hello main
Thread Thread-1
Thread thread = new Thread(() -> {
while (true){
System.out.println("Thread" + Thread.currentThread().getName());
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
System.out.println("Exit!");
return;
}
}
});
thread.start(); <-- 무한루프 쓰레드 실행 1초마다 쓰레드 출력
System.out.println("Hello "+Thread.currentThread().getName()); <-- 스레드가 대기에 걸리므로 가장 먼저 main쓰레드로 출력
Thread.sleep(3000L); <-- 3초간 대기
thread.interrupt(); <- 자고있는 쓰레드 깨우기 => 무한루프 쓰레드의 try-catch에 걸려서 return 구문을 통해 탈출하게 된다
//출력
Hello main
ThreadThread-2
ThreadThread-2
ThreadThread-2
Exit!
Thread thread = new Thread(() -> {
try {
Thread.sleep(3000L); <-- 3초 대기
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
});
thread.start();
System.out.println("Hello " + Thread.currentThread().getName());
thread.join(); <-- thread가 다시 시작할때까지 기다렸다가 뒤의 코드를 실행(3초후)
System.out.println(thread + " is finished");
//출력
Hello main
<3초 대기>
Thread[Thread-2,5,] is finished
* join도 쓰레드를 기다리면서 대기하므로 join에도 try-catch문으로 보호해줘야한다
try {
Thread.join();
} catch(InterruptedException e) {
throw new IllegalStateException(e);
}
sleep() <- 대기를 걸면 main스레드의 우선순위를 올려서 먼저 처리후 sleep시간 이후에 나머지를 다른쓰레드에서 처리한다
Interrupt() <- 자고있는(대기중인) 쓰레드를 깨운다
join() <- 대기중인 쓰레드를 기다렸다가 다음 코드를 실행한다
*여기서 문제 - sleep()으로인해 대기중인 쓰레드에 접근하는 경우를 방지하기 위해 InterruptedException try-catch구문을 통해 제어를 하게되는데 join()또한 대기중인 쓰레드를 기다리기위해 대기중이므로 try-catch를 써서 보호해야한다. 따라서 수십 수백개의 쓰레드를 코드로 제어해야할 경우 상당히 복잡해지는 상황이 발생한다