본격 스레드 진입 전 먼저 기초를 알아보면
참고:
더 정확히 말하자면 스택 영역은 각 스레드 별로 하나의 실생 스택이 생성되는데,
따라서 스레드 수 만큼 스택이 생성된다.
스레드를 추가하면 그만큼 스택도 스레드 수 만큼 증가한다.
스레드를 만들 때는 Thread
클래스를 상속 받는 방법과,
Runnable
인터페이스를 구현하는 방법이 있다.
public class HelloThread extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + ": run()");
}
}
public class HelloThreadMain {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": main() start"); // main 이라는 스레드가 떠서 메인 메서드인 sout 내용을 실행
HelloThread helloThread = new HelloThread();
System.out.println(Thread.currentThread().getName() + ": start() 호출 전");
helloThread.start(); // helloThread.run(); 을 호출하면 안된다! start로 해야 별도의 스레드에서 run()이 실행
System.out.println(Thread.currentThread().getName() + ": start() 호출 후");
System.out.println(Thread.currentThread().getName() + ": main() end");
}
}
RUN
main: main() start
main: start() 호출 전
main: start() 호출 후
main: main() end
Thread-0: run()
Process finished with exit code 0
HelloThread
스레드 객체를 생성한 다음 start()
메서드 호출시 자바는 스레드를 위한 별도의 스택 공간을 할당start()
를 호출해야 스택 공간을 할당 받고 스레드가 작동한다. 즉 별도의 스레드에서 run()
이 실행된다는 뜻Thread-0
,Thread-1
과 같은 임의의 이름을 부여Thread-0
스레드가 사용할 전용 스택 공간이 마련됨Thread-0
스레드는 run()
메서드의 스택 프레임을 스택에 올리면서 run()
메서드를 시작스레드를 공부하며 이 과정을 실제 손으로 그려보는 것도 추천한다.
start()
를 통해 Thread-0
스레드의 실행 스택 공간이 할당받았다.start()
를 호출해서 Thread-0
스레드가 시작되면서 Thread-0
스레드가run()
을 실행start()
메서드를 빠져나온다.그래서 가끔 출력된 것을 보면 순서가 바뀌어있는 경우가 있다.
// main 스레드가 빨리 실행된 경우
main: main() start
main: start() 호출 전
main: start() 호출 후
main: main() end
Thread-0: run()
// Thread-0 스레드가 빨리 실행된 경우
main: main() start
main: start() 호출 전
Thread-0: run()
main: start() 호출 후
main: main() end
start()
를 호출하는 스레드도 전무 main 스레드고,Thread-0
은 HelloThread에 있는 run()
을 실행시키는 것이다.만약 CPU 코어가 2개라면 main과 Thread-0을 동시에 실행 시킬 수 있다.
또 하나의 CPU 코어에 시간을 나누어 실행될 수도 있다.
한 스레드가 얼마나 오랜기간 실행되는지도 보장하지 않기 때문에
한 스레드가 먼저 다 수행된 다음에 다른 스레드가 수행될 수도 있고, 둘이 완전히 번갈아 가면서 수행되는 경우도 있다.
스레드는 동시에 실행되기 때문에 스레드 간에 실행 순서나 기간을 보장하지 않는다.
이것이 멀티스레드..!