[JAVA - 점프 투 자바 #25]

스레드

동작하고 있는 프로그램을 프로세스라고 한다. 보통 한 개의 프로세스는 한 가지의 일을 하지만, 스레드를 이용하면 한 프로세스 내에서 두 가지 또는 그 이상의 일을 동시에 할 수 있다.
  1. Thread
  2. Join
  3. Runnable
    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()로 쓰레드를 실행한다.
     }
    }
    

    run or start 의 차이

    Thread 클래스를 extends를 사용해 상속했기 때문에 start 메서드를 실행하면 run 메서드가 수행된다. 
    Thread 클래스는 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) {
        }
        System.out.println(this.seq + " thread end.");  // 쓰레드 종료 
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {  // 총 10개의 쓰레드를 생성하여 실행한다.
            Thread t = new Sample(i);
            t.start();
        }
        System.out.println("main end.");  // main 메서드 종료
    }
}

순서가 일정치 않은 것을 보면 스레드는 순서에 상관없이 동시에 실행된다.

쓰레드가 종료하기 전에 main 메서드가 종료됐다.

쓰레드 종료후에 main 메서드가 종료되게 하려면?

join

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.");
    }
}

스레드를 활용한 프로그래밍을 할 때 가장 많이 실수하는 부분이 스레드가 종료되지 않았는데

스레드가 종료된 줄 알고 그다음 작업을 진행하게 만드는 일이다.

스레드가 모두 종료된 후 그다음 작업을 진행해야 할 때 join 메서드를 꼭 기억하자.

Runnable

Thread 객체를 만들 때 앞서 살펴본 예처럼 Thread 클래스를 상속하여 만들기도 하지만 주로 Runnable 인터페이스를 사용한다.

왜냐하면 Thread 클래스를 상속하면 Thread 클래스를 상속한 클래스가 다른 클래스를 상속할 수 없기 때문이다.

import java.util.ArrayList;

public class Sample implements Runnable {
    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 Thread(new Sample(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.");
    }
}

카테고리: ,

태그:

업데이트: