참고 : program / process / thread
https://velog.io/@seongmin42/program-process-thread
public class SampleThread extends Thread {
int seq;
public SampleThread(int seq) {
this.seq = seq;
}
public void run() {
System.out.println(this.seq + " thread start."); // 쓰레드 시작
try {
Thread.sleep(1000); // 1초 대기
} catch (Exception e) {
}
System.out.println(this.seq + " thread end."); // 쓰레드 종료
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) { // 총 10개의 쓰레드를 생성하여 실행한다.
Thread t = new SampleThread(i);
t.start();
}
System.out.println("main end."); // main 메서드 종료
}
}
0 thread start.
5 thread start.
4 thread start.
1 thread start.
3 thread start.
2 thread start.
9 thread start.
7 thread start.
main end.
6 thread start.
8 thread start.
5 thread end.
4 thread end.
8 thread end.
6 thread end.
7 thread end.
1 thread end.
9 thread end.
2 thread end.
3 thread end.
0 thread end.
sampleThread.start()
를 실행하면 sampleThread
의 run()
메서드가 수행된다. 다만, 쓰레드는 순서대로 실행되지 않고, 순서와 상관없이 동시에 실행된다. 특히 main 메서드는 쓰레드가 종료되기 전에 종료됐다.
모든 쓰레드가 종료된 후에 main 메서드를 종료시키기 위해, join()
메서드가 필요하다.
import java.util.ArrayList;
public class SampleThread extends Thread {
int seq;
public SampleThread(int seq) {
this.seq = seq;
}
public void run() {
System.out.println(this.seq+" thread start.");
try {
Thread.sleep(1000 * this.seq);
}catch(Exception e) {
}
System.out.println(this.seq+" thread end.");
}
public static void main(String[] args) {
ArrayList<Thread> threads = new ArrayList<>();
for(int i=0; i<10; i++) {
Thread t = new SampleThread(i);
t.start();
threads.add(t);
}
for(int i=0; i<threads.size(); i++) {
Thread t = threads.get(i);
try {
t.join(); // t 쓰레드가 종료할 때까지 기다린다.
}catch(Exception e) {
}
}
System.out.println("main end.");
}
}
0 thread start.
2 thread start.
1 thread start.
4 thread start.
7 thread start.
3 thread start.
5 thread start.
0 thread end.
9 thread start.
8 thread start.
6 thread start.
1 thread end.
2 thread end.
3 thread end.
4 thread end.
5 thread end.
6 thread end.
7 thread end.
8 thread end.
9 thread end.
main end.
join()
메서드는 쓰레드가 종료될 때까지 기다리게 하는 메서드이다. 쓰레드가 종료된 후 그 다음 로직을 수행해야 할 때 필요한 메서드이다.
자바에서는 인터페이스만이 다중 상속이 가능하기 때문에, 보통 쓰레드를 Runnable 인터페이스를 구현하는 방식으로 사용한다.
import java.util.ArrayList;
public class SampleThread implements Runnable {
int seq;
public SampleThread(int seq) {
this.seq = seq;
}
public void run() {
System.out.println(this.seq+" thread start.");
try {
Thread.sleep(1000);
}catch(Exception e) {
}
System.out.println(this.seq+" thread end.");
}
public static void main(String[] args) {
ArrayList<Thread> threads = new ArrayList<>();
for(int i=0; i<10; i++) {
Thread t = new Thread(new SampleThread(i));
t.start();
threads.add(t);
}
for(int i=0; i<threads.size(); i++) {
Thread t = threads.get(i);
try {
t.join();
}catch(Exception e) {
}
}
System.out.println("main end.");
}
}
3 thread start.
6 thread start.
1 thread start.
2 thread start.
7 thread start.
8 thread start.
5 thread start.
4 thread start.
0 thread start.
9 thread start.
6 thread end.
2 thread end.
3 thread end.
1 thread end.
8 thread end.
7 thread end.
4 thread end.
0 thread end.
9 thread end.
5 thread end.
main end.
위의 방식은 Thread의 생성자로 Runnable 인터페이스를 구현한 객체를 넘기는 방법이다. Thread 객체를 상속하는 것보다 유연한 방법이다.
위에서 알 수 있듯, 쓰레드는 순서에 영향을 받지 않는다. start()
가 호출되었다고 바로 실행되는 구조가 아니기 때문이다. 우선 실행대기 상태에 들어가게 되며, OS 스케쥴러에 의해 결정된 스케쥴에 따라 자신의 차례가 오면 실행되는 구조이다.
스레드의 상태는 다음과 같다.
자세한 내용은 https://velog.io/@khsb2012/java-study-week10 참고
https://wikidocs.net/230
https://velog.io/@khsb2012/java-study-week10