쓰레드의 구현과 실행
1) Thread 클래스 상속
class MyThread extends Thread {
public void run () {
}
}
사용
MyThread t1 = new MyThread();
t1.start();
2) Runnable 인터페이스 구현
class MyThread2 implements Runnable {
public void run() {
}
}
사용
Runnable r = new MyThread2();
Thread t2 = new Thread(r);
t2.start();
예제 코드
public class Ex13_1 {
public static void main(String[] args) {
ThreadEx1_1 t1 = new ThreadEx1_1();
Runnable r = new ThreadEx1_2();
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
class ThreadEx1_1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(this.getName());
}
}
}
class ThreadEx1_2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
}
}
}
실행 결과
- 지금은 순차적으로 t1, t2 쓰레드가 수행된 것 같지만, for문의 반복 횟수를 500씩으로 늘리면 다음과 같이 된다.
000011100000000000000000000000000000000000001111111111111111111111111111110000
000000000000000000011111111011111001110000100110111111111111111110111100000000
000000000011111111111100011111000000001111110001111111110000000000000000000001
111111100000001000001111111111000000000000000000000000000000000000000000000111
111111101111111111111111111100000001111111111111111110000000001111110000000000
000000000001111111111111000000111111111111111111111000000111100000000000111111
111111111111110001101111001110000011111111000000000000000000001100000000000111
111110000000000000000000000000000000001111111110000000011110000000000000011111
111111110001110000000001111111111111100000001111111111111111111111111111111111
111111111111000000000000001111111111111111100010011111111111111111111100111111
111111110000000000000000000000011111111100111111111111100000011000111110001100
000000011111000011000011000111110001111100000011000000000000000000000001111100
0000000000000000000000111111100001111111111111111111111111111111
쓰레드의 실행 - start()
- 쓰레드를 생성한 후에
start()
를 호출해야 쓰레드가 작업을 시작한다.
- 위의 예제의 경우 순차적으로 실행된 것 같지만, t1이 먼저
start()
됐다고 해서 반드시 먼저 수행되는 것은 아니다.
- 쓰레드를
start()
하는 것은 "실행 가능한 상태" 를 만드는 것이지 바로 실행하는 것이 아니기 때문
- 언제 실행할지는 OS의 스케쥴러가 결정한다. (OS 스케쥴러가 실행순서를 결정)
run()을 작성하는데 start()를 호출하는 이유?
- start를 통해 새로운 Call stack(호출 스택)을 생성한다.
- 새롭게 생성된 호출 스택에서 run()이 돌아간다고 생각하면 된다.
- 각각의 쓰레드가 자기만의 호출 스택을 갖고 실행됨 (따라서 독립적 수행이 가능)