스레드를 자바에선 JVM에 의해 관리 된다. 프로세스는 적어도 하나의 쓰레드를 가지고 있는데, 자바는 main쓰레드를 필수로 갖게 된다.
자바에서 스레드를 생성하는 방법은 1.스레드를 상속받거나 2.Runnable인터페이스를 구현하는 방법이 있다.
1. 스레드 상속
스레드의 실행은 run()메서드를 통해 실행된다. run() 함수를 오버라이드 하면 된다.
class ThreadEx1_1 extends Thread {
public void run() {
for (int i=0; i<5; i++){
System.out.println(getName());
}
}
}
2.runnable interface
인터페이스를 구현하여 쓰레드 객체를 생성하면 된다. 마찬가질 run()메서드를 구현해야 한다.
class ThreadEx1_2 implements Runnable {
@Override
public void run() {
for (int i=0; i<5; i++){
System.out.println(Thread.currentThread().getName());
public static native Thread currentThread();
//Thread의 static 메소드로 자신의 스레드를 참조함 <- 자신의 스레드의 getName()을 부르는 거임
}
}
}
아래는 runnable interface를 통한 스레드 객체 생성 방식이다.
public Thread(Runnable task) {
this(null, null, 0, task, 0, null);
} // <- Thread 생성자: Runnable 객체를 받아서 Thread 객체를 생성함
public void run() {
Runnable task = holder.task; // Thread에 저장된 Runnable 객체 가져오기
if (task != null) {
Object bindings = scopedValueBindings(); // 스코프 바인딩 정보 가져오기
runWith(bindings, task); // 실제 Runnable 실행
} // <- Thread의 run() 메서드: 저장된 Runnable의 run() 메서드를 실행함
}
스레드는 thread.start()를 통해 실행되고,실행되면 run()을 통해 진행한다. thread.run()을 진행하면 새로운 스택을 실행하는 것이 아닌 main쓰레드의 스택을 사용하므로 주의해야 한다.
public static void main(String[] args) {
ThreadEx1_1 t1 = new ThreadEx1_1(); // thread 자손 클래스의 인스턴스 생성
Runnable r = new ThreadEx1_2(); // runnable을 구현한 클래스의 인스턴스 생성
Thread t2 = new Thread(r);
t1.start();//스레드를 생성하고 사용될 호출스택 생성 -> run() 만들어진 호출스택에 생성
t2.start();
t1 = new ThreadEx1_1();
t1.start(); //스레드 다시 실행시 예외 발생
}
}
thread.start()와 thread.run() 차이
- thread.run() Main Thread Call Stack ┌────────────────────────────┐ │ main() │ │ └─ thread.run() 호출 │ │ └─ run() 메서드 실행 │ └────────────────────────────┘ - thread.start() Main Thread Call Stack New Thread Call Stack ┌────────────────────────┐ ┌─────────────────────┐ │ main() │ │ run() │ │ └─ thread.start() 호출 │ └─────────────────────┘ └────────────────────────┘
Thread 객체의 이름을 가져오는 메서드는 getName()이다.
하지만 Runnable 인터페이스를 구현한 객체는 Thread가 아니기 때문에 getName() 메서드를 직접 호출할 수 없다.
따라서 현재 실행 중인 스레드의 이름을 얻고 싶다면, Thread.currentThread()를 호출해 현재 스레드 객체를 얻은 뒤, getName()을 호출해야 한다.
this 가 가르키는 객체
- thread - thread
- runnable - runnable 구현 객체