프로레스, 스레드, 멀티스레드?

|

프로세스란?

  1. 프로세스란 단순히 실행중인 프로그램이라고 할 수 있습니다.
  2. 즉, 사용자가 작성한 프로그램이 운영체제에 의헤 메모리공간을 할당받아 실행 중인것을 이야기합니다.
  3. 이러한 프로세스는 프로그램에 사용되는 데이터와 메모리등의 자원 그리고 스레드로 이루어집니다.

스레드란?

  1. 스레드란 프로세스내에서 실제로 작업을 수행하는 주체를 말합니다.
  2. 모든 프로세스에는 한개 이상의 스레드가 존재하여 작업을 수행합니다.
  3. 또한, 두 개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스라고 합니다.

멀티스레드란?

  1. 일반적으로 하나의 프로세스는 하나의 스레드를 가지고 작업을 수행하게 됩니다.
  2. 하지만 멀티쓰레드란 하나의 프로세스내에서 둘 이상의 스레드가 동시에 작업을 수행하는 것을 의미합니다.
  3. 또한, 멀티프로세스는 각 프로세스가 독립적인 메모리를 가지고 별도로 실행되지만, 멀티스레드는 각 스레드가 자신이 속한 프로세스의 메모리를 공유한다는 점이 다릅니다.
  4. 멀티스레드는 각 스레드가 자신이 속한 프로세스의 메모리를 공유하므로, 시스템자원의 낭비가 적습니다.
  5. 또한, 하나의 스레드가 작업을 할 때 다른 스레드가 별도의 작업을 할 수 있어 사용자와의 응답성도 좋아집니다.

멀티스레드의 장단점

장점

  1. 응답성 : 예를 들어 채팅프로그램을 멀티스레드화 하면, 채팅의 일부분이 전송이 되지 않거나 큰 파일을 전송하고 있어도, 사용자는 다른 스레드를 통해서 다른 사용자와 대화가 가능하다.

  2. 자원공유 : 스레드는 자동적으로 그들이 속한 프로세스의 자원들과 메모리를 공유한다. 코드 공유의 이점은, 한 응용프로그램 같은 주소공간내에서 여러개의 다른 활동성 스레드를 가질 수 있기 때문입니다.

  3. 경제성 : 멀티 프로세스처럼 여러개의 프로세스에 메모리와 자원을 할당하면 비용이 많이 발생하지만, 스레드는 한 프로세스 내에서 자원 ( 데이터, 메모리 등 의 자원)을 공유하기 때문에 경제적입니다.

  4. 쓰레드 간의 통신이 필요한 경우에도 별도의 자원을 이용하는 것이 아니라 전역 변수의 공간 또는 동적으로 할당된 공간인 힙(Heap) 영역을 이용하여 데이터를 주고받을 수 있다. 또한 멀티쓰레드에서는 쓰레드간에 스택영역(메모리의 값이 아닌 주소만 보관)과 힙 영역을 공유합니다.

  5. 데이터 영역과 힙 영역을 통해 데이터 교환이 가능하다. 쓰레드 사이에서의 데이터 교환에서는 특별한 기법이 필요없다.

단점

  1. 멀티스레드를 기반으로 할 경우, 동일한 자원에 접근할 수 있기 떄문에 프로그래밍시 신경써줘야한다.

  2. 서로 다른 쓰레드가 데이터와 힙 영역을 공유하기 때문에 어떤 쓰레드가 다른 쓰레드에서 사용중인 변수나 자료구조에 접근하여, 엉뚱한 값을 읽어오거나 수정할 수 있습니다. 그렇기 멀티스레드 환경에서는 동기화 작업이 필요합니다.

  3. 동기화 작업을 제대로 하지 않으면, 락 문제가 일어날 수 있고, 데이터 병목 현상이 일어날수있습니다.

힙 영역

  • 자바에서 힙영역은 사용자가 동적으로 할당할 수 있는 공간입니다. 그래서 new 명령으로 생성하는 인스턴스는 모조리 힙영역에 보관이 됩니다. 할당받은 메모리 주소를 잃어버려 가바지 컬렉션에 의해서 지워질 떄까지 혹은 jvm이 종료될때까지 유지가 됩니다.

멀티스레드와 멀티프로세스의 차이

  1. 멀티스레드는 하나의 프로세스에서 여러개의 쓰레드가 동작하며, 모든 스레드가 모두 같은 주소공간에서 동작하여 같은 메모리를 공유합니다.
  2. 결국 멀티스레드는 하나의 프로그램안에서의 병렬처리의 이점을 맛볼수있고, 멀티프로세싱은 여러 개의 프로그램들을 병렬로 처리할 수 있습니다.

자바에서 스레드를 실행하는 방법

Thread 클래스로부터 직접 생성

  • java.lang.Thread 클래스로부터 작업 스레드 객체를 직접 생성 하려면 Runnable을 매개값으로 갖는 생성자를 호출해야 한다. Runnable은 작업 스레드가 실행할 수 있는 코드를 가지고 있는 객체라고 해서 붙여진 이름이다. Runnable에는 run() 메소드 하나가 정의되어 있는데, 구현 클래스는 run()을 재정의해서 작업 스레드가 실행할 코드를 작성해야 한다.
// 1번 방법
Runnable task = new Task();
Thread thread = new Thread(task);

// 2번 방법, 쓰레드 생성자를 호출할 때 Runnable 익명 객체를 매개값으로 사용한다
Thread thread = new Thread(new Runnable() {
    public void run() {
        // 스레드가 실행하는 코드!!
    }
});

// 3번 방법, 람다식을 매개값으로 사용하는 방법
Thread thread = new Thread(() -> {
    // 스레드가 실행할 코드
})

Thread를 상속받은 자식 클래스로부터 생성

  • Thread의 하위 클래스로 작업 스레드를 정의하면서 작업 내용을 포함시킬 수도 있다. Thread 클래스를 상속한 후 run 메소드를 overriding해서 스레드가 실행할 코드를 작성하면 된다.

public class WorkerThread extends Thread {
    @Override
    public void run(){
        // 스레드가 실행할 코드
    }
}

Thread thread = new Thread(){
    public void run(){
        // 스레드가 실행할 코드
    }
}

thread.start();

Thread 우선 순위

  • 동시성과 병렬성
    • 동시성은 멀티작업을 위해서 하나의 코어에서 멀티스레드가 번갈아가며 실행하는 성질을 말하고, 병렬성은 멀티 작업을 위해 멀티코어에서 개별 스레드를 동시에 실행하는 성질을 말합니다. 싱글코어 CPU을 이용한 멀티스레드 작업을 하나의 코어가 번갈아가면서 스레드를 실행하기 때문에 마치 보기에는 동시에 실행하는 것처럼 보이지만, 사실은 빠르게 번갈아가면서 실행하고 있습니다.
  • 스레드 스케쥴링
    • 스레드의 개수가 코어보다 많을 경우 스레드를 어떤 순서로 실행해야 하는지 결정해야 하는데, 이것을 스레드 스케줄링이라고 합니다.
  • 자바의 스레드 스케쥴링
    • 우선 순위 방식과 순환할당 방식을 사용합니다
    • 우선 순위 방식은 프로그래머가 스레드의 순서를 결정할 수 있습니다. 프로그래머가 지정한 우선 순위대로 실행상태를 더 많이 가져갈수 있습니다. 반대로 순환 할당 방식은 프로그래머가 따로 스레드를 제어하지 않을 경우 자바 프로그램 내에서 자동으로 순서를 결정해서 실행합니다.

데몬 스레드

  • 주 스레드의 작업을 돕는 보조적인 역활을 수행하는 스레드입니다.
  • 주 스레드가 종료되면 데몬 스레드는 강제적으로 종료됩니다.
    • 워드 프로세서의 자동저장 기능, 미디어플레이어의 동영상 및 음악 재생, 가비지 컬렉터 등등

스레드풀

  • 스레드폭증
    • 병렬처리 작업이 많아지면 스레드의 개수가 증가한다
    • 스레드 생성과 스케쥴링으로 인해 CPU가 바빠지고, 메모리 사용량이 늘어난다
    • 따라서 애플리케이션의 성능이 급격히 저하된다
  • 스레드풀
    • 작업처리에 사용되는 스레드를 제한된 개수만큼 미리 생성
    • 작업 큐(Queue)에 들어오는 작업들을 하나씩 스레드가 맡아 처리한다
    • 작업 처리가 끝난 스레드는 작업결과를 애플리케이션으로 전달합니다
    • 스레드는 다시 작업큐에서 새로운 작업을 가져와 처리한다

Comments