Java

쓰레드 Thread, 작업을 수행하는 단위

조충희 2025. 4. 25. 15:35

쓰레드
Thread

프로세스에서 작업을 수행하는 단위

⭐process
프로그램이 실행되면
OS로부터 메모리를 할당받아
프로세스 상태가 된다.

⭐thread
하나의 프로세스에는
하나 이상의 쓰레드를 가지고 된다.
쓰레드는 실제 작업을 수행하는 단위이다.

메모리[@프로세스@프로세스@프로세스]
ㄴ@프로세스[#쓰레드#쓰레드#쓰레드]

 

 

🤔Why?

단일 쓰레드 환경이라면
메모리 소모가 큰 작업을 할때 다른 작업을 할 수 없게 된다.
자바에서는 이럴때 run() 메소드를 활용해서 다른 작업을 동시에 할 수 있다.

 

 

                  Run: cpu는 하나의 작업만을 수행
                     |  
Start => Runnable <=> Not Runnable(sleep): 스케줄러가 메모리에 올라온 프로세스들의 작업순서를 결정
                     |
                  Dead

 

package _thread;
/**
 * 4.25
 * 쓰레드 Thread
 *
 */
public class WhatIsThread {

    /*
    Thread란

    ⭐process
    프로그램이 실행되면
    OS로부터 메모리를 할당받아
    프로세스 상태가 된다.

    ⭐thread
    하나의 프로세스에는
    하나 이상의 쓰레드를 가지고 된다.
    쓰레드는 실제 작업을 수행하는 단위이다.

    메모리[@프로세스@프로세스@프로세스]
            ㄴ@프로세스[#쓰레드#쓰레드#쓰레드]

    ⭐multi threading
    여러 쓰레드가 동시에 수행되는 프로그래밍을 말한다.
    여러 작업이 동시에 실행되는 효과를 만들 수 있다.

    각각의 쓰레드는 자신만의 변수, 메서드 등 작업 공간을 가질 수 있다.

    💀단, 멀티쓰레딩을 할 때 주의점이 있다.
    각 쓰레드 사이에는 공유하는 자원을 가질 수 있는데
    여러 쓰레드가 자원을 공유하여 작업을 수행한다면
    서로 자원을 차지하려는
    race condition
    발생 가능🐶

    이에 따라 의도하지 않은 동작이 발생시킬 수 있다.

     */
}

 

 

😎How? 1.상속을 활용해서 쓰레드 만들기 (작업자 만들기)

Thread 클래스 상속
class xxx extends Thread

1.Thread 상속
2.run() 메서드 재정의
3.Thread 객체 생성
4.start(호출)

서브 작업자가 해야 할 일은
run() 메서드 안에 정의한다.

그리고 start 메서드를 통해서 쓰레드한테 일을 시작하도록 명령한다.
그러면 다른 쓰레드가 run()에 정의된 일을 수행한다.

 

예제1) 상속을 통해 쓰레드 만들기

package _thread;
/**
 * 4.25
 * 쓰레드 2강
 * <p>
 * 1.상속을 활용해서 쓰레드 만들기 (작업자 만들기)
 */
public class Worker extends Thread {

    private String name;

    public Worker(String name) {
        this.name = name;
    }
    /*
    서브 작업자가 해야 할 일은
    run() 메서드 안에 정의한다.

    그리고 start 메서드를 통해서 쓰레드한테 일을 시작하도록 명령한다.
    그러면 다른 쓰레드가 run()에 정의된 일을 수행한다.
     */

    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            System.out.println("worker" + name + ": " + i);

            try {
                Thread.sleep(1000); // 1000millis = 1초 쉬어라

            } catch (InterruptedException e1) {
                System.out.println("외부신호에 따른 예외발생");
                e1.printStackTrace(); //예외가 발생한 부분을 좀 더 상세히 출력

            }
        }
    }

}//end of class Worker
package _thread;
/**
 * 4.25
 * 쓰레드 2강
 * <p>
 * 1.상속을 활용해서 쓰레드 만들기 (작업자 만들기)
 */
public class WorkerMainTest {
    //main thread - 일을 도맡아 하는 녀석
    public static void main(String[] args) {
        //사용하는 방법
        System.out.println("========== 메인 쓰레드 시작 ==========");

        //현재 쓰레드가 누구인가
        System.out.println(Thread.currentThread());

        //작업자 subthread 하나 만들기
        Worker worker = new Worker("워커1");
        worker.start(); //worker가 위임받은 작업을 시작하라는 명령어

        System.out.println("========== 메인 쓰레드 종료 ==========");


    }//end of main
}//end of class



😎 How? 2.인터페이스를 구현해 쓰레드 만들기 (작업자 만들기)
class xxx implement Runnable

1.Runnable 인터페이스 구현
2.run() 메서드 작성
3.Thread 객체 생성
4.start() 호출

💀인터페이스를 활용해서 쓰레드를 start() 시키려면
그냥은 start() 메서드가 없어서 동작을 시키지 못한다.
Thread subT1 = new Thread(worker2);
subT1.start();

👍인터페이스를 구현하는 방식이 더 일반적이다.

 

예제2) 인터페이스를 구현해 쓰레드 만들기

package _thread;
/**
 * 4.25
 * 쓰레드 2강
 * <p>
 * 2.인터페이스를 이용해 쓰레드 만들기 (작업자 만들기)
 */
public class Worker2 implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 101; i++) {
            System.out.print(i + "\t");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (i % 10 == 0) {
                System.out.println();
            }
        }
    }

}//end of class

인터페이스를 구현한 쓰레드를 호출하는 방식은 조금 더 복잡하다

package _thread;
/**
 * 4.25
 * 쓰레드 2강
 * <p>
 * 2.인터페이스를 이용해 쓰레드 만들기 (작업자 만들기)
 */
public class Worker2MainTest {

    //main thread
    public static void main(String[] args) {

        // 상속을 통한 쓰레드 생성
//        Worker worker1 = new Worker("워커");
//        worker1.start();

        //사용하는 방법
        System.out.println("========== 메인 쓰레드 시작 ==========");
        //현재 쓰레드가 누구인가
        System.out.println(Thread.currentThread());

        // 인터페이스를 활용해서 쓰레드를 start() 시키는 방법
        Worker2 worker2 = new Worker2();
//        worker2.start();
        /*인터페이스를 사용했을 때
        start() 메서드가 없어서 동작을 시키지 못한다.
         */

        Thread subT1 = new Thread(worker2);
        subT1.start();
        System.out.println("========== 메인 쓰레드 종료 ==========");

    }//end of main
}//end of class