활동/독서

[Do it! 점프 투 자바] 07.자바 심화학습 (스레드 구현 및 실행 메서드 start(), run(), join())

ByeongJun 2023. 9. 15. 16:57
반응형

* 본 게시물은 이지스퍼블리싱 [Do it! 점프 투 자바] 서평단 미션 수행 및 학습 목적으로 작성하였습니다.
 

  모든 내용, 디자인, 이미지, 편집 구성의 저작권은 이지스퍼블리싱(주)와 지은이에게 있으며

  학습 목적으로 내용을 재구성하여 작성했음을 밝힙니다. 문제시 삭제하도록 하겠습니다.


 

07-05 스레드

동작하고 있는 프로그램을 프로세스(process)라고 한다. 보통 한 개의 프로세스는 한 가지의 일을 하지만, 스레드(thread)를 이용하면 한 프로세스 내에서 **두 가지 또…

wikidocs.net

 

 

 

 

 

Thread

 

동작하고 있는 프로그램을 프로세스(Process)라고 한다. 

 

보통 한 개의 프로세스는 한 가지의 일을 하지만, 

스레드(Thread)를 이용하면 한 프로세스 내에서 두 가지 또는 그 이상의 일을 동시에 할 수 있다. 

 

public class Sample extends Thread {
    public void run() {  // Thread 를 상속하면 run 메서드를 구현해야 한다.
        System.out.println("thread run.");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.start();  // start()로 쓰레드를 실행한다.
    }
}

Thread 클래스를 상속하면 run() 메서드를 구현해야 한다

구현하지 않을 경우 컴파일러 오류를 발생시킨

run() 메서드는 스레드가 실행될 때 호출되는 메서드로써, 

이 메서드를 구현하여 스레드가 어떤 작업을 수행할지 정의한다. 

 

또한, 스레드를 실행시키기 위해선 start() 메서드를 반드시 사용해야 하는데 

스레드를 실제로 시작하고, 스레드가 자체적으로 run() 메서드를 호출해 작업을 수행한다.

 

 

 

public class Sample extends Thread {
    int seq; // 스레드 고유 번호를 저장할 변수

    public Sample(int seq) {
        this.seq = seq; // 생성자를 통해 스레드에 고유 번호를 할당
    }

    public void run() {
        System.out.println(this.seq + " thread start.");  // 스레드 시작을 알리는 메시지 출력
        try {
            Thread.sleep(1000);  // 1초 동안 스레드를 일시정지
        } catch (Exception e) {
            // sleep() 메서드는 예외 처리가 필요하므로 예외를 무시
        }
        System.out.println(this.seq + " thread end.");  // 스레드 종료를 알리는 메시지 출력
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {  // 0부터 9까지 10개의 스레드를 생성하여 실행
            Thread t = new Sample(i);  // 스레드 객체를 생성하고 고유 번호를 전달
            t.start(); // 스레드를 시작하고 run() 메서드 실행
        }
        System.out.println("main end.");  // main 메서드 종료를 알리는 메시지 출력
    }
}

총 10개의 스레드를 실행시킬 때 어떤 스레드인지 확인하기 위해

스레드마다 생성자 순서와 스레드 시작, 종료를 출력하게 했다. 

 

 Thread.sleep(1000);  시작과 종료 사이에 1초의 간격이 생기도록 했다.

또한 main 메서드 종료 시 'main end'를 출력하도록 했다. 

 

 

 

스레드는 병렬로 실행되므로 스레드 실행 순서가 항상 동일하지 않을 수 있다. 

 

 

 

[case 1]                        [case 2]                       [case 3]

 

스레드 실행 순서는 운영체제 및 JVM의 스케줄링에 따라 달라질 수 있기 때문에 

 main end.  문자열의 출력 순서처럼 스레드 시작 및 종료 메시지의 순서가 다를 수 있는 것이다. 

 

 

 

 

 

숨은글자찾기 하는 것도 아니고 뒤죽박죽 출력되는 

 main end.  문자열이 가장 마지막에 출력되게 하기 위해서는 어떻게 해야할까? 

import java.util.ArrayList;

public class Sample extends Thread {
    int seq;
    public Sample(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 Sample(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.");
    }
}

 

생성된 스레드를 담기 위해 ArrayList 객체인 threads를 만든 후

스레드 생성 시 생성된 객체를 threads에 저장했다.

 

main 메서드가 종료되기 전에 thread 객체에 담긴 각각 스레드에

스레드가 종료될 때까지 기다리게 하는 메서드인

join() 메서드를 호출해 스레드가 종료될 때까지 대기하도록 했다.

 

 

 

 main end.  문자열이 가장 마지막에 출력되는 것을 확인할 수 있다. 

 

스레드를 활용한 프로그래밍을 할 때 

스레드가 종료되지 않았는데 스레드가 종료된 줄 알고

그 다음 작업을 진행하지 않도록 유의해야 한다.

 

그 다음 작업을 진행해야 할 때 join() 메서드를 사용한다.

반응형