본문 바로가기
Application/Java

[Jump2Java] 07장 쓰레드

by 윤루트 2021. 9. 16.

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));
  • 상속에 대해서 좀 더 유연하게 발전한 프로그램

댓글