Thread
쓰레드는 프로세스와 연관이 깊은 개념이다.
먼저 프로세스는 간단히 말해서 실행 중인 프로그램이다. 프로그램을 실행하면 OS로부터 실행에 필요한 자원을 할당받아 프로세스가 된다. 프로세스는 프로그램을 수행하는데 필요한 데이터와 메모리 등의 자원 그리고 쓰레드로 구성되어 있으며 프로세스의 자원을 이용해서 실제로 작업을 수행하는 것이 바로 쓰레드이다.
Thread 구현
쓰레드를 구현하는 방법은 Thread 클래스를 상속하는 방법과 Runnable 인터페이스를 구현하는 방법으로 두가지가 있다. 클래스를 상속받으면 다른 클래스를 상속받을 수 없기 때문에 인터페이스를 구현하는 방법이 일반적이다.
Thread 구현 (1) - Thread 클래스 상속
쓰레드를 구현한다는 것은 단지 쓰레드를 통해 작업하고자 하는 내용으로 run()의 구현부를 작성하는 것에 불과하다.
다음은 ThreadEx1 클래스에서 Thread 클래스를 상속받고 run() 메서드를 오버라이딩하여 getName() 메서드를 반복 호출하고 있는 코드이다.
Thread 클래스를 상속받았기 때문에 조상인 Thread 클래스의 메서드를 직접 호출할 수 있다.
public class ThreadTest {
public static void main(String[] args) {
ThreadEx1 t1 = new ThreadEx1();
t1.start();
}
}
class ThreadEx1 extends Thread {
@Override
public void run() {
super.run();
for(int i=0; i<5; i++) {
System.out.println(getName());
}
}
}
Thread 구현 (2) - Runnable 인터페이스 구현
먼저 Runnable 인터페이스는 다음과 같이 run() 메서드만 정의되어 있다.
package java.lang;
@FunctionalInterface
public interface Runnable {
/**
* Runs this operation.
*/
void run();
}
다음의 ThreadEx2 클래스를 보면 Runnable 인터페이스를 구현하고 run() 메서드 내에서 Thread 클래스의 static 메서드인 currentThread()를 호출하고 있음을 확인할 수 있다.
Thread 클래스를 상속받은 것이 아니기 때문에 쓰레드에 대한 참조를 얻어 와야 하는 것이다.
main() 메서드를 보면 Thread 클래스를 상속받았을 때와의 차이점을 하나 더 확인할 수 있다.
Runnable 인터페이스를 구현한 클래스의 인스턴스를 생성한 다음, 이를 Thread 클래스의 생성자에게 매개변수로 제공하고 있다.
매개변수가 있는 생성자를 이용함으로써 상속을 하지 않고도 외부로부터 run()을 제공받을 수 있는 것이다.
public class ThreadTest {
public static void main(String[] args) {
ThreadEx1 t1 = new ThreadEx1();
t1.start();
ThreadEx2 r = new ThreadEx2();
Thread t2 = new Thread(r);
t2.start();
}
}
class ThreadEx1 extends Thread {
@Override
public void run() {
super.run();
for(int i=0; i<5; i++) {
System.out.println(getName());
}
}
}
class ThreadEx2 implements Runnable {
@Override
public void run() {
for(int i=0; i<5; i++) {
System.out.println(Thread.currentThread().getName());
}
}
}
Thread의 실행
쓰레드를 생성했다고 해서 자동으로 실행되는 것은 아니다.
start()를 호출해야만 비로소 쓰레드가 실행된다.
실제로는 start()가 호출된다고 해도 바로 실행되는 것은 아니고, 일단 실행 대기 상태에 있다가 자신의 차례가 되어야 실행된다.
cf. 한 번 실행이 종료된 쓰레드는 다시 실행할 수 없다. 즉, 하나의 쓰레드에 대해 start()가 한 번만 호출될 수 있다.
public class ThreadTest {
public static void main(String[] args) {
ThreadEx1 t1 = new ThreadEx1();
t1.start();
ThreadEx2 r = new ThreadEx2();
Thread t2 = new Thread(r);
t2.start();
}
}
'Java' 카테고리의 다른 글
Thread의 동기화 (0) | 2024.10.05 |
---|