자바의 정석을 통해 공부한 내용을 요약하였습니다.
- 프로세스(Process) : 실행 중인 프로그램
- 쓰레드(Thread) : 프로세스의 자원을 이용해서 실제로 작업을 수행하는 것
- 멀티 태스팅(멀티 프로세싱) : 동시에 여러 프로세스를 실행시키는 것
- 멀티 쓰레딩 : 하나의 프로세스 내에 동시에 여러 쓰레드를 실행시키는 것
쓰레드를 구현하는 방법은 2가지가 있다.
- Thread클래스를 상속
- Runnable 인터페이스를 구현
Runnable인터페이스를 구현하는 방법은 재사용성이 높고 코드의 일관성을 유지할 수 있기 때문에 보다 객체지향적인 방법이라 할 수 있다.
또한 Java는 클래스의 다중상속이 허용되지 않기 때문에 인터페이스를 구현하는 것이 일반적이다.
// Thread 클래스를 상속
class MyThread extends Thread {
public void run() { // 작업내용 } // Thread 클래스의 run()을 오버라이딩
}
// Runnable 인터페이스 구현
class MyThread implements Runnable {
public void run() { // 작업내용 } // Runnable인터페이스의 run()을 구현
}
Runnable 인터페이스는 오로지 run()만 정의되어 있는 간단한 인터페이스이다.
Runnable r = new ThreadEx1_2(); // Runnable을 구현한 클래스의 인스턴스를 생성
Thread t2 = new Thread(r); // 생성자 Thread(Runnable target)
Runnable인터페이스를 구현한 경우 Runnable인터페이스를 구현한 클래스의 인스턴스를 생성한 다음, 이 인스턴스를 Thread클래스의 생성자 매개변수로 제공해야 한다.
class ThreadEx1_2 implements Runnable {
public void run() {
for(int i=0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
}
}
}
또한 Runnable을 구현하면 Thread클래스의 static메서드인 current Thread()를 호출하여 쓰레드에 대한 참조를 얻어 와야 호출이 가능하다.
static Thread currentThread() - 현재 실행중인 쓰레드의 참조를 반환
String getName() - 쓰레드의 이름을 반환
Thread(Runnable target, String name)
Thread(String name)
void setName(String name)
쓰레드의 이름은 위와 같은 생성자나 메서드를 통해서 지정 또는 변경할 수 있다.
쓰레드를 생성하고 나서 start()를 호출해야만 쓰레드가 실행된다.
t1.start(); // 쓰레드 t1 실행
t2.start(); // 쓰레드 t2 실행
start()가 호출되었다고 해서 바로 실행되는 것은 아니다.
우선 대기 상태로 차례를 기다렸다가 차례가 되었을 때 실행된다.
물론 대기 큐에 아무것도 없을 때는 바로 실행상태가 된다.
쓰레드의 실행순서는 OS의 스케줄러에 의해 결정된다.
또한 한번 실행이 종료된 쓰레드는 다시 실행할 수 없다.
즉, start()는 한 번만 호출할 수 있다.
만약 쓰레드의 작업을 한번 더 수행할 경우 새로운 쓰레드를 생성한 후에
start()를 호출해야 한다.
새로운 쓰레드를 생성하지 않고 start()를 호출하게 된다면 예외가 발생한다.
- main메서드에서 쓰레드의 start()를 호출
- start()는 새로운 쓰레드를 생성하고, 쓰레드가 작업하는데 사용될 호출스택을 생성
- 새로 생성된 호출스택에 run()이 호출되어 쓰레드가 독립적인 공간에서 작업을 수행
- 스케줄러가 정한 순서에 의해서 번갈아 가면서 실행