[Java 기능] 쓰레드(Thread)

2022. 2. 18. 14:23·Java

쓰레드(Thread)

  • 디스크에 존재하는 프로그램이 실행되면 OS로부터 메모리를 할당받아 프로세스 상태가 됨
  • 실제로 작업이 수행되기 위해서는 CPU를 점유해야하는데, 이때 작업 단위를 쓰레드라고 함
  • 하나의 프로세스는 하나 이상의 쓰레드를 가짐

 

Multi-threading

  • 하나의 프로그램에서 동시에 여러 작업이 일어날 수 있음
  • 이는 쓰레드가 동시에 실행되는 것이 아니라 쓰레드 간에 switch가 발생하는 것임 
  • OS의 스케줄러가 CPU를 골고루 점유하도록 쓰레드를 배분하는 역할을 함
  • 쓰레드는 각각 자신만의 작업공간(context)를 가짐 (자원이 각각 저장됨)
  • 여러 쓰레드가 CPU를 번갈아 점유하게 되면서 context switch가 발생함

 

멀티 쓰레드에서 발생할 수 있는 문제 상황

  • 각 쓰레드 사이에는 공유하는 자원(resource ; 변수, 메모리 등)이 있을 수 있음 (자바에서는 static instance)
  • 공유 자원(static resource)를 각 쓰레드가 차지했을 때 문제가 발생할 수 있음
  • 여러 쓰레드가 자원을 공유하여 작업 시 서로 자원을 차지하려는 자원 경쟁(race condition)이 발생할 수 있음
  • race condition이 발생하면 각 쓰레드에서 공유 자원을 변경하게 되고 쓰레드마다 다른 값을 가지게 될 수 있음
  • 여러 쓰레드가 공유하는 자원 중 race condition이 발생할 수 있는 부분을 임계 영역(critical section)이라고 함
  • 이를 방지하기 위해 critical section에 lock을 걸어 동기화(synchronization)를 구현해야함
  • 한 쓰레드가 공유 자원을 사용하고 있으면 다른 쓰레드는 사용할 수 없게끔 해줌 (순차적으로 사용)
  • 자바에서는 synchronized method, synchronized block으로 동기화를 구현함

 

※ 참고 ※

- 웹 프로그래밍에서는 웹서버 자체에 멀티쓰레드가 구현되어 있어서 따로 멀티쓰레드를 구현할 일이 없음

- 안드로이드 프로그래밍 등에서 쓰레드를 직접 생성하고 쓰레드 간 메세지를 주고 받아야 할 일이 발생할 수 있음

 

자바에서 쓰레드 만들기

  1. Thread 클래스를 상속받음
  2. 이미 다른 클래스를 상속받은 경우(자바는 단일 상속만 지원하므로 Thread 상속받지 못함) Runnable 인터페이스와run() 메서드를 구현

 

Thread 클래스를 상속받을 때
  • 쓰레드가 될 클래스가 Thread 클래스를 상속받음
  • Thread의 메서드 start()를 호출하면 쓰레드가 시작되고, run()메서드가 호출됨
package ch20;

class MyThread extends Thread {	// Thread의 모든 메서드 사용 가능
	
	public void run() {
		
		int i;
		for(i = 0; i <= 200; i ++) {
			System.out.print(i + "\t");
		}
	}
}

public class ThreadTest {

	public static void main(String[] args) {
		
		System.out.println(Thread.currentThread() + "start"); // 실행되는 thread 정보 출력
		
		MyThread th1 = new MyThread();
		MyThread th2 = new MyThread();
		
		// 총 세개의 쓰레드 돌아감 (+ main 쓰레드)
		th1.start();	// run 메서드 호출
		th2.start();
		
		System.out.println(Thread.currentThread() + "end");
	}

}

 

Runnable 인터페이스와 run() 메서드를 구현
  • Runnable 인터페이스를 implement해서 구현
  • Runnable 인스턴스를 매개변수로 받는 Thread 클래스의 생성자를 이용하여 쓰레드 생성
class MyThread implements Runnable {

...

}

public class ThreadTest {

	public static void main(String[] args) {
    
            MyThread runnable = new MyThread();
            Thread th1 = new Thread(runnable);	// 매개변수 runnable 인스턴스
            Thread th2 = new Thread(runnable);
    
}
  • Runnable 익명 객체를 생성하여 쓰레드를 생성할 수도 있음
Runnable run = new Runnable() {	// 익명 객체 생성 -> 쓰레드

    @Override
    public void run() {

        System.out.println("run");
    }

};

run.run();

 

Thread Status

  • 쓰레드가 시작되면 쓰레드 풀(pool)에 들어옴 → Runnable 상태 : CPU를 배분 받으면 바로 실행 가능한 상태
  • 쓰레드가 종료되면 Dead 상태로 전환  
  • Not Runnable 상태 : CPU를 점유할 수 없는 상태 (계속 남아있으면 좀비 쓰레드)
  • 자바의 상태전이 메서드
  • sleep(time) : 지정된 시간동안 Not Runnable 상태. 시간이 지나면 Runnable 상태로 돌아옴
  • wait() : 리소스가 available할 때까지 Not Runnable 상태. notify() 메서드를 호출하면 Runnable 상태로 돌아옴.
  • join() : 하나의 쓰레드가 다른 쓰레드의 결과를 참조할 때, 참조하는 쓰레드는 다른 쓰레드가 끝날 때까지 Not Runnable 상태. 참조되는 쓰레드가 끝날 때 Runnable 상태로 돌아옴.
  • wait()이 호출되고 notify()가 호출되지 않거나, join()의 경우 다른 쓰레드가 종료되지 않으면 Not Runnable에 계속 남아있게 됨 → 좀비 쓰레드 상태
저작자표시 비영리 변경금지 (새창열림)

'Java' 카테고리의 다른 글

[Java 기능] Thread 클래스의 여러 메서드  (0) 2022.02.18
[Java 기능] Decorator Pattern 활용한 커피머신 프로그램  (0) 2022.02.17
[Java 기능] 그외 여러가지 입출력 클래스들  (0) 2022.02.17
'Java' 카테고리의 다른 글
  • [Java 기능] 동기화 구현 (1) - 리소스 하나를 공유하는 경우
  • [Java 기능] Thread 클래스의 여러 메서드
  • [Java 기능] Decorator Pattern 활용한 커피머신 프로그램
  • [Java 기능] 그외 여러가지 입출력 클래스들
suaring
suaring
개발 공부 로그
  • suaring
    Sue's devlog
    suaring
  • 전체
    오늘
    어제
    • 분류 전체보기 (123)
      • Algorithm (2)
      • WEB (8)
      • Spring (26)
      • Java (83)
      • Kotlin (1)
      • Database (1)
      • Infra (0)
      • Git (1)
      • devlog (1)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
suaring
[Java 기능] 쓰레드(Thread)
상단으로

티스토리툴바