프로그램을 실행할때 프로세스는 OS에서 자원을 할당받는다.
프로세스는 자원과 쓰레드로 구성되어있으며
쓰레드는 호출스택을 생성해 작업을 작업을 수행한다.
프로세스라는 공장에서 쓰레드라는 일꾼들이 있다고 생각하면 이해하기 쉽다.
프로세스의 자원에 따라 생성 가능한 쓰레드 수가 정해지지만
보통 그 수를 넘는 일이 없기 때문에 깊게 고려하지 않아도 된다.
멀티쓰레딩은 하나의 프로세스 내에서 여러개의 쓰레드를 동시에 수행하는 것이다. CPU의 코어는 한번에 하나의 작업만 처리할 수 있다.
이 말은 하나의 코어는 한번에 하나의 쓰레드를 수행할 수 있다는 것이다.
그러나 쓰레드의 수는 보통 코어의 수보다 훨씬 많다.
코어는 여러 쓰레드를 빠르게 번갈아 처리하며 마치 동시에 처리하는 것처럼 보이게 한다.
쓰레드는 Thread 클래스와 Runnable 인터페이스 둘중 하나를 상속해
구현 할 수 있다.
Thread클래스를 상속받으면 다른 클래스를 상속 받을 수 없기 때문에
(자바에서는 클래스의 다중상속을 지원하지 않는다)
Runnable인터페이스를 상속받아 구현하는 것이 일반적이다.
쓰레드를 구현하려면 run() 메서드의 몸통만 채워주면 된다.
public class MyThreadEx {
public static void main(String[] args) {
MyThread myThread = new MyThread();
//Runnable 인터페이스를 구현한 클래스의 인스턴스는
//아래와 같이 Thread 클래스의 생성자의 매개변수로 제공해야한다.
Runnable runnable = new MyThread2();
Thread myThread2 = new Thread(runnable);
myThread.start();
myThread2.start();
// 결과:
// Thread-0
// Thread-0
// Thread-0
// Thread-0
// Thread-0
// Thread-1
// Thread-1
// Thread-1
// Thread-1
// Thread-1
}
}
class MyThread extends Thread{
@Override
public void run() {
for (int i=0 ; i <5 ; i++){
//Thread의 메서드로 현재 쓰레드의 이름을 반환한다.
System.out.println(getName());
}
}
}
class MyThread2 implements Runnable{
@Override
public void run() {
//Runnable은 run만 정의돼있는 인터페이스이므로
//현재 쓰레드 인스턴스를 생성해 이름을 불러와야한다.
Thread thread = Thread.currentThread();
for (int i=0 ; i < 5 ; i++){
System.out.println(thread.getName());
}
}
}
메인 메서드에서 start()를 호출했는데
run()메서드의 몸통이 실행되었다.
왜일까?
start()는 쓰레드를 실행하는 (새로운 호출 스택을 생성하는)
메서드고 run()은 그저 몸통에 있는 작업을 수행만 하는 메서드이기 때문이다.
start()메서드가 실행되면 새로운 호출 스택이 생성되고
그 호출 스택에서 run()이 수행된다.
모든 쓰레드의 수행이 끝나면 프로그램은 종료된다