Thread

김국민·2025년 2월 20일

JAVA

목록 보기
9/21

프로세스와 스레드

프로세스란?

실행중인 프로그램을 말한다.
프로그램을 실행하면 os로부터 실행에 필요한 자원을 할당받아 프로세스가 된다.

프로세스는 프로그램을 수행하는데 필요한 데이터와 메모리 등의 자원 그리고 스레드로 구성되어 있다

멀티스레드

멀티 스레드의 장점

  • CPU의 사용률을 향상시킨다
  • 자원을 보다 효율적으로 사용할 수 있다
  • 사용자에 대한 응답성이 향상된다
  • 작업이 분리되어 코드가 간결해진다

여러 사용자에게 서비스를 해주는 서버 프로그램의 경우 멀티쓰레드로 작성하는 것은 필수적이다!
하나의 서버 프로세스가 여러개의 스레드를 생성해서 스레드와 사용자의 요청이 일대일로 처리되도록 프로그래밍 해야한다

장점만 있는것은 아니다
프로세스 내에서 자원을 공유하면서 작업을 하기 때문에 발생할 수 있는 문제가 있다

  • 동기화
  • 교착상태 : 두 스레드가 자원을 점유한 상태에서 서로 상대편이 점유한 자원을 사용하려고 기다리느라 진행이 멈춰있는 상태를 말한다

스레드 구현과 실행

자바에서 스레드를 구현하는 방법은 두가지이다

  • Thread클래스를 상속받기
  • Runnable인터페이스 상속받기 (주로 이 방법을 사용한다)
  1. 스레드 클래스 상속
class MyThread extends Thread{
	public void run(){}
    }
  1. Runnable 인터페이스 상속
class MyThread implements Runnable{
	public void run(){}
  	}

Runnable 인터페이스는 오로지 run()만 정의되어있는 인터페이스다
이 인터페이스를 구현하기 위해 해야 할 일은 추상메서드인 run()만 구현하면 된다.

Runnable 인터페이스로 스레드 생성하기

public class Main {
    public static void main(String[] args) {

        Runnable r = new ThreadEx();
        Thread th = new Thread(r);

    }
}

class ThreadEx implements Runnable{
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            //Thread.currentThread() - 현재 실행중인 스레드를 반환함
            System.out.println(Thread.currentThread().getName());
        }
    }
}
  1. Runnable 인터페이스를 상속받은 클래스를 만들고 인스턴스 생성
  2. Thread 클래스의 생성자의 매개변수로 위에서 만든 인스턴스를 매개변수로 넣는다

Runnable로 만든 스레드 사용하기

Thread클래스를 상속받으면 자손 클래스에서 Thread클래스의 메서드를 직접 호출할 수 있다.
하지만 Runnable을 구현하면 Thread클래스의 static 메서드인 currentThread()를 호출하여 스레드에 대한 참조를 얻어야된다

스레드 실행

스레드를 생성했다고 해서 자동으로 실행되지 않는다
start()를 호출해야만 스레드가 실행된다

start()를 호출해서 바로 실행되는 것이 아니라 OS의 스케줄러가 작성한 스케줄에 의해 결정된다.

한번 종료된 스레드는 다시 실행할 수 없다.
만약 스레드의 작업을 한 번 더 수행해야 한다면 새로운 스레드를 생성해야한다.

start()와 run()

스레드를 실행시킬 때 run()이 아닌 start()를 호출한다
run과 start의 차이를 알아보자

  • run()은 스레드를 실행시키는 것이 아니라 단순히 클래스에 선언된 메서드를 호출하는 것일 뿐
  • start()는 새로운 스레드가 작업을 실행하는데 필요한 호출스택을 생성한 다음에 run()을 호출해서 생성된 호출스택에 run()이 올라가게한다.
  1. main메서드는 스레드의 start()를 호출한다
  2. start()는 새로운 스레드를 생성하고 작업하는데 사용될 호출스택 생성한다
  3. 새로 생성된 호출스택에 run()이 호출되어 독립된 공간에서 작업을 수행한다
  4. 호출스택이 2개이므로 스케줄러가 정한 순서에 의해 번갈아 수행된다.
  5. 마지막으로 run()의 수행이 끝나면 호출스택은 사라진다
profile
개발지망생

0개의 댓글