2021-9-14 점프 투 자바 쓰레드
7-5 쓰레드(Thread)
동작하고 있는 프로그램을 프로세스라고 한다. 보통 한 개의 프로세스는 한 가지의 일을 하지만, 이 쓰레드를 이용하면 한 프로세스 내에서 두가지 또는 그 이상의 일을 동시에 할 수 있게 된다.
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();
}
}
Test 클래스가 Thread 클래스를 상속했다. Thread 클래스의 run 메소드를 구현하면 위 예제와 같이 test.start() 실행시 test객체의 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);
}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개의 쓰레드를 실행시키는 예제이다.
결과는 다음과 비슷하게 나올 것이다.
0 thread start.
4 thread start.
6 thread start.
2 thread start.
main end.
3 thread start.
7 thread start.
8 thread start.
1 thread start.
9 thread start.
5 thread start.
0 thread end.
4 thread end.
2 thread end.
6 thread end.
7 thread end.
3 thread end.
8 thread end.
9 thread end.
1 thread end.
5 thread end.
0번 쓰레드부터 9번 쓰레드까지 순서대로 실행이 되지 않고 순서와 상관없이 동시에 실행된다. 쓰레드가 종료되기 전에 main 메소드가 종료되어버린다.
Join
위 예제에서는 쓰레드가 모두 수행되고 종료되기 전에 main 메소드가 종료되어버렸다.
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.");
}
다음 예제는 생성되는 쓰레드를 담기 위해서 ArrayList 객체인 threads를 만든 후 쓰레드 생성시 생성된 객체를 threads에 저장한다.
main 메소드가 종료되기 전에 threads에 담긴 각각의 thread에 join 메소드를 호출하여 쓰레드가 종료될때까지 대기하도록 한다.
쓰레드의 join 메소드는 쓰레드가 종료될때까지 기다리게 하는 메서드이다.
Runnable
보틍 쓰레드 객체를 만들 때 위의 예처럼 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.");
}
}
Thread를 extends하던 것에서 Runnable을 implements하도록 변경되었다. 그리고 Thread를 생성하는 분도 다음과 같이 변경했다.
Thread t = new Thread(new Test(i));