Thread
- 쓰레드를 이용하면 한 프로세스 내에서 두 가지 또는 그 이상의 일을 동시에 할 수 있게 된다.
public class Test extends Thread {
public void run() {
System.out.println("thread run.");
}
public static void main(String[] args) {
Test test = new Test();
test.start();
}
}
// 출력 결과: thread run.
- Test 클래스가 Thread를 extends 했기 때문에 main에서 start() 메소드로 run 메소드가 실행된다.
public class Test extends Thread {
int seq;
public Test(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++) {
Thread t = new Test(i);
t.start();
}
System.out.println("main end.");
}
}
- 총 10번의 thread를 실행시키는 예제
- int형의 seq으로 몇 번째 thread인지 구분한다.
- main 메소드 종료 시 종료 메시지 출력
출력 결과
2 thread start.
1 thread start.
0 thread start.
3 thread start.
4 thread start.
5 thread start.
6 thread start.
7 thread start.
main end.
9 thread start.
8 thread start.
9 thread end.
3 thread end.
5 thread end.
0 thread end.
6 thread end.
8 thread end.
4 thread end.
7 thread end.
2 thread end.
1 thread end.
- 순서에 상관 없이 동시에 실행된다.
- thread가 전부 끝나기 전에 main 메소드가 끝난다.
Join
- thread가 종료될 때까지 기다리게 하는 메소드이다.
import java.util.ArrayList;
public static void main(String[] args) {
ArrayList<Thread> threads = new ArrayList<Thread>();
for(int i=0; i<10; i++) {
Thread t = new Test(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.");
}
- 생성된 thread를 담을 ArrayList 객체를 미리 만든 후 하나씩 저장한다.
- threads 에 담긴 각각의 thread에 join 메소드를 호출하여 thread가 종료될 때까지 대기하도록 변경하였다.
출력 결과
3 thread start.
1 thread start.
2 thread start.
4 thread start.
0 thread start.
5 thread start.
6 thread start.
7 thread start.
8 thread start.
9 thread start.
2 thread end.
3 thread end.
8 thread end.
9 thread end.
7 thread end.
5 thread end.
6 thread end.
0 thread end.
1 thread end.
4 thread end.
main end.
- thread 프로그래밍 시 가장 많이 실수하는 부분이 바로 thread가 종료되지 않았는데 종료된 것으로 인지하여 그 다음 로직을 수행하게 만드는 일이다.
- thread가 종료된 후 그 다음 로직을 수행해야 할 때 꼭 필요한 것이 바로 이 join 메소드이다.
Runnable
- 보통 thread 객체를 만들 때 위의 예처럼 Thread를 상속하여 만들기도 하지만 보통 Runnable 인터페이스를 구현하도록 하는 방법을 많이 사용한다.
import java.util.ArrayList;
public class Test implements Runnable {
int seq;
public Test(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<Thread>();
for(int i=0; i<10; i++) {
Thread t = new Thread(new Test(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.");
}
}
- Runnable 인터페이스는 run 메소드를 구현하도록 강제한다.
- Thread 를 생성하는 부분을 다음과 같이 변경했다.
Thread t =new Thread(new Test(i));
- 상속에 대해서 좀 더 유연하게 발전한 프로그램
댓글