억대 연봉을 위한 인간수업
article thumbnail
Published 2023. 5. 14. 14:24
[Java] Thread란? Develop/Java
반응형

Process & Thread & Fork

Process

  • 프로세스란? cpu에 의해 메모리에 올라가 실행 중인 프로그램
  • 메모리 공간을 포함한 독립적인 실행 공간을 갖는다.
  • JVM(java virtual Machine)은 하나의 프로세스로 실행되며, 동시에 여러 작업을 수행하기 위해 멀티 쓰레드를 지원한다.

 

Thread

  • 쓰레드란? 프로세스의 자원을 이용해 실제 작업을 수행하는 주체
  • java에서는 JVM에 의해 관리된다.
  • 프로세스 안에서 한 개 이상의 쓰레드가 작업을 하는데, 1개면 단일 쓰레드, 2개 이상이면 멀티 쓰레드라 한다.
  • 스택을 제외한 프로세스의 모든 섹션을 공유하는 경량 프로세스
  • thread는 fork의 비효율성을 극복하기 위해 사용

 

fork

  • 프로세스를 복제하는 것으로 새로운 프로세스를 만드는 것
  • fork는 프로세스 복제 시 System call이 발생하는데, 복제를 위해 다른 작업을 할 수 없게 되고 cpu자원을 많이 잡아먹는다
    • 비효율적임
  • fork는 프로세스를 만들고 프로세스 간의 context switching을 하게 됨

 


 

Fork와 Thread 차이점

  • thread와 process는 스케쥴링의 단위가 되고, login control flow인 PC를 가지며 동시에 동작
  • thread는 code, data를 공유하지만 프로세스는 그렇지 않다.
  • thread는 생성,종료, context switching 비용이 적다
  • process와 다르게 커널의 간섭 없이 thread간에 빠르게 정보교환을 할 수 있다.
  • 각 thread는 다른 프로세서에서 병렬적으로 활동 가능
  • 쓰레드는 자신이 원하는 작업을 테스크 형태로 생성

 

리눅스에서는?

  • 리눅스에서 process와 thread의 구조가 완전 똑같다. 단지 공유하는 메모리가 있냐 없냐의 차이만 존재
  • 프로세스 복제 시 다른 작업을 할게 없어서 리눅스에서는 별 차이가 없다.
  • context switching 비용도 별 차이 없다.
  • process와 다르게 커널의 간섭 없이 thread간에 '빠르게 정보교환을 할 수 있다' 정도 차이만 존재
  • 각 thread의 병렬적 활동이 가능한건 fork에서도 가능하다.
  • 단지 윈도우에서만 fork와 thread의 차이가 좀 더 있을 뿐이다.

 

Thread 상태

쓰레드 프로그래밍을 하다 보면 쓰레드의 행동을 직접적으로 제어해야 하는 경우가 발생한다.

이런 경우 쓰레드를 제어하기 위해 쓰레드의 상태를 알아야 하는데, getState()메소드를 통해 상태를 알 수 있다.

쓰레드의 상태는 6가지가 있다.

  1. NEW : 쓰레드 객체가 생성한 상태로, 아직 start()메소드가 호출되지 않고 실행 준비가 완료된 상태
  2. RUNNABLE : 쓰레드 실행이 가능한 상태
  3. BLOCKED : 쓰레드 차단되어 있는 상태로 잠금(lock)이 풀릴 때 까지 기다리는 상태
  4. WAITING : 쓰레드 대기 중인 상태로 다른 쓰레드의 작업 완료를 기다리는 상태
  5. TIMED_WAITING : 쓰레드 정해진 시간 동안 대기하는 상태, WAITING과의 차이는 정해진 시간 동안 대기 하는 것
  6. TERMINATED : 쓰레드의 실행을 마친 상태

https://www.geeksforgeeks.org/lifecycle-and-states-of-a-thread-in-java/

 

 

Thread 구현 방법

자바에서 쓰레드를 구현하는 방법은 두 가지가 존재한다.

1. Runnable 인터페이스 구현

2. Thread 클래스 상속

 

두 방법 중 Runnable인터페이스를 구현하는 방법을 많이 사용하는데, 그 이유는 자바는 다중 상속을 받는 것이 불가능하기 때문에 쓰레드 클래스를 extends 할경우 다른 클래스의 상속이 불가하기 때문이다. 그래서 Runnable을 사용해 상속 문제를 해결하여 사용한다.

 

두 방법 모두 run()메소드에 작성하면 된다. 

// Runnable 사용
public class TaskThread implements Runnable{
	내용...
    thread1.run() // 쓰레드 실행
}

//Thread 상속받아 사용
public class TaskThread2 extends Thread{
	내용...
    thread2.run() // 쓰레드 실행 2
}

 

 

Runnable 사용 예시

TaskRunnuble 클래스

public class TaskRunnuble implements Runnable{
    private int counter = 0;
    private boolean running = true;
    @Override
    public void run() {
        while(running){
            counter++;
            System.out.println(counter);
            if(counter >= 1000) running = false;
        }
    }
}

Main

public class Main {
    public static void main(String[] args) {
        TaskRunnuble testR = new TaskRunnuble();
        testR.run();
    }
}

 

 

 

 

반응형
profile

억대 연봉을 위한 인간수업

@회뜨는참치

이 글이 당신에게 조금이라도 도움이 된다면 좋겠습니다.