[Java] 쓰레드(Thread)

이병수·2024년 1월 10일
0

Java

목록 보기
22/27
post-thumbnail

쓰레드(Thread)


1. 프로세스와 쓰레드

프로세스와 쓰레드의 차이점에 대해 알고 넘어가자.

프로세스란?

  • 운영체제로부터 자원을 할당받는 작업의 단위를 의미한다.

  • 일반적으로 cpu에 의해 메모리에 올려져 실행중인 프로그램을 말한다.

  • 프로세스의 구조에는 OS가 프로그램을 위한 프로세스를 할당해줄 때, 프로세스 안에 프로그램 Code와 Data 그리고 메모리 영역(Stack, Heap)을 함께 할당해준다.

    • Code : Java main 메소드와 같은 코드를 의미

    • Data : 프로그램이 실행 중 저장할 수 있는 저장공간을 의미

      • 전역변수, 정적변수(static), 배열 등 초기화 된 데이터 공간
    • Memory (메모리 영역)

      • Stack : 지역변수, 매개변수, 리턴 변수를 저장하는 공간

      • Heap : 프로그램이 동적으로 필요한 변수를 저장하는 공간 ( new() )

  • 각 프로그램은 프로세스를 통해 Code, Data, Memory(Stack, Heap)를 OS로부터 할당받는다.


쓰레드란?

  • 프로세스가 할당 받은 자원을 이용하는 실행의 단위

  • 프로세스 안에서 실질적으로 작업을 실행하는 단위이며, 자바에서는 JVM에 의해 관리된다.

  • 프로세스에는 적어도 한 개 이상의 쓰레드가 있다.

  • 따라서 프로세스가 작업중인 프로그램에서 실행 요청이 들어오면 쓰레드를 만들어 명령을 처리하도록 한다.


쓰레드 자원

  • 프로세스 안에 여러 쓰레드들은 실행을 위한 프로세스 내의 주소 공간이나 메모리공간(Heap)을 공유한다.

  • 쓰레드들은 각각 명령처리를 위한 자신만의 메모리공간(Stack)도 할당 받는다.

  • 즉, 쓰레드가 생성이 된다면 스택 영역을 나뉘게 되며, 힙 영역과 메서드 영역을 공유한다.


따라서 Java 프로그램을 실행하면 JVM 프로세스 위에서 실행이 되며
Java 프로그램 쓰레드는 Java Main 쓰레드부터 실행되며 JVM에 의해 실행하게 된다.


2. 멀티 쓰레드

public static void main(String[] args) {
	// Do Something!
}
  • 자바에서 main 메서드 안에서 단순히 코딩을 작성했다면 싱글 쓰레드를 이용한 것이다.

싱글 쓰레드

프로세스 안에서 하나의 쓰레드만 실행되는 것

  • main() 메서드만 실행 시켰을 경우, 싱글 쓰레드라고 부른다.

  • 따라서 JVM의 메인 쓰레드가 종료되면 JVM도 같이 종료가 된다.


멀티 쓰레드

프로세스 안에서 여러개의 쓰레드가 실행되는 것

  • 하나의 프로세스는 여러개의 실행단위(쓰레드)를 가질 수 있으며 이 쓰레드들은 프로세스의 자원을 공유하게 된다.

  • 따라서 메인 쓰레드 외에 다른 쓰레드를 생성하여 여러개의 실행 흐름을 만들 수 있다.

  • 자바는 멀티 쓰레드를 지원한다.

  • 메인 쓰레드 안에 하나 이상의 쓰레드를 만드는 순간, 멀티 쓰레드가 된다.


멀티 쓰레드 장점

  • 여러개의 쓰레드를 통해 여러개의 작업을 동시에 할 수 있어서 성능이 좋아진다.

  • 스택을 제외한 모든 영역에서 메모리를 공유하기 때문에 자원을 효율적으로 사용 가능

  • 응답 쓰레드와 작업 쓰레드를 분리하여 빠르게 응답을 줄 수 있다. (비동기)


멀티 쓰레드 단점

  • 동기화 문제가 발생할 수 있다.

    • 프레서스의 자원을 공유하면서 작업을 하기 때문에, 서로 자원을 사용하려고 하는 순간 충돌이 발생한다.
  • 교착상태(데드락)이 발생할 수 있다.

    • 둘 이상의 쓰레드가 서로의 자원을 원하는 상태가 되었을 때 서로 작업이 종료되기만을 기다리며 더이상 진행하지 못하는 상태를 의미한다.

참고

동시성 (Concurrency)

멀티 작업을 위해 하나의 코어에서 멀트 쓰레드가 번갈아가며 실행하는 성질을 의미한다.

  • 싱글 코어 CPU를 이용한 멀티 쓰레드 작업은 병렬적으로 보이지만 사실 번갈아가면서 실행하는 동시성 작업이며, 그 순간이 워낙 빨라서 병렬성으로 보이는 것 뿐이다.

* 병렬성 (Paralleism)

멀티 작업을 위해 멀티 코어에서 개별 쓰레드를 동시에 실행하는 성질

  • 말 그대로 코어가 하나가 아닌 여러개에서 각각의 쓰레드들을 처리하는 것

3. Thread와 Runnable

자바에서 쓰레드를 구현하고 실행하는 방법

1. Thread Class 이용

public class TestThread extends Thread{
	@Override
    public void run() {
    	// 쓰레드 수행 작업
    }
}

...

TestThread thread = new TestThread();  	// 쓰레드 생성
thread.start();							// 쓰레드 실행
  • Thread를 상속 받고 run() 메서드를 오버라이딩하여 해당 run() 메서드 안에 코드를 작성

  • 다른 main 메서드를 만들어서 해당 Thread를 상속받은 클래스의 인스턴스를 생성하여 run() 메서드를 호출하는 것이 아닌 !!! , start() 메서드를 통해서 실행한다.

2. Runnable 인터페이스 이용

public class TestRunnable implements Runnable {
	@Override
    public void run() {
    	// 쓰레드 수행작업
    }
}

...

Runnable run = new TestRunnable();
Thread thread = new Thread(run);		// 쓰레드 생성

thread.start();							// 쓰레드 실행
  • Runnable 인터페이스를 구현하면 딱 하나의 추상 메서드인 run()을 오버라이딩하여 코드를 작성한다.

  • 해당 Runnable 인터페이스 타입의 변수 안에 인터페이스를 구현한 클래스의 객체의 메모리 주소값을 대입한 뒤

  • Thread 타입의 변수에 위의 Runnable 인터페이스 타입 변수를 넣는다.

  • start()를 통해 실행한다.

// Runnable 람다식

Runnable task = () -> {
	// Do Something!
}

Thread thread = new Thread(task);
thread.setName("Thread");

thread.start();

정리

  • Thread Class 보다 Runnable 인터페이스를 구현하는 것이 더 많이 사용된다.

  • 클래스 상속은 다중 상속이 되지 않고, 인터페이스는 다중 구현을 하기 때문이다.

  • 그렇기 때문에 클래스를 상속하게 된다면 확장성에 매우 떨어지게 된다.


참고

멀티 쓰레드에서의 여러개의 쓰레드의 실행 순서나 걸리는 시간은 OS의 스케줄러가 처리하기 때문에 프로그래머는 알 수 없다.


링크

profile
백엔드 개발자가 되고 싶어요

0개의 댓글