Nulog
article thumbnail

Thread(1)  스레드의 정의와 생성 방법

Thread(2) 동기화

Thread(3) 스레드의 상태와 실행 제어

프로세스와 스레드 (Process & Thread)

  1.  프로세스란?
  • CPU에 의해 메모리에 올려져 실행중인 프로그램
  • 프로그램은 자신만의 메모리 공간을 포함한 독립적인 실행 환경을 가지고 있다. 우리가 사용하는 프로그램 중 일부는 여러 프로세스 간 상호작용을 하는 것일수도 있다. 
  • 자바 JVM(Java Virtual Machine)은 주로 하나의 프로세스로 실행되며, 동시에 여러 작업을 수행하기 위해서 멀티 스레드를 지원하고 있다.  

 

2) 스레드란?

  • 프로세스 안에서 실질적으로 작업을 실행하기 위해 필요한 명령의 흐름을 말한다.
  • 즉, 스레드는 하나의 코드 실행 흐름이다. 프로그램이 실행되기 위해 일하는 일꾼이라고 비유할 수 있다.
  • 스레드는 자바에서 JVM(Java Virtual Machine)에 의해 관리된다.
  • 프로세스에는 적어도 한개 이상의 스레드가 있으며, Main 스레드 하나로 시작하여 스레드를 추가 생성하게 되면 멀티 스레드 환경이 된다.
  • 이러한 스레드들은 프로세스의 리소스를 공유하기 때문에 효율적이긴 하지만 잠재적인 문제점에 노출될 수도 있다. 

메인 스레드와 멀티 스레드

싱글 스레드 애플리케이션

JAVA 애플리케이션을 실행하면 가장 먼저 실행되는 메서드는 main 메서드이다.

메인 스레드가 이 main 메서드의 코드를 처음부터 끝까지 차례대로 실행시키며, 코드가 끝났거나 return문을 만나면 실행을 종료한다.

어떤 소스코드가 싱글 스레드로 작성되었다면, 애플리케이션이 실행하여 프로세스될 때 오직 메인 스레드 하나만 가지는 싱글 스레드 프로세스가 된다.

만약 메인 스레드에서 또 다른 스레드를 실행해야 한다면, 이는 멀티 스레드 프로세스로 진행된다.

멀티 스레드 애플리케이션

하나의 프로세스는 여러 스레드를 가질 수 있다. 이는 동시에 작업을 수행하는 것을 의미한다.

카톡으로 사진을 업로드하면서 동시에 메시지를 주거나 받을 수 있다. 하나의 프로그램이 여러 작업을 동시에 수행하기 위해선 여러 스레드가 필요하다.

스레드 생성방법

Runnable 인터페이스 구현 vs Thread 클래스 상속

  Runnable 인터페이스 구현 Thread 클래스 상속
장점 재사용성이 높다.
코드의 일관성을 유지할 수 있어 보다 객체지향적이다.
상속받은 클래스의 객체만으로 스레드 생성이 가능하다.
단점 Thread 객체를 생성해 인자를 전달해야 한다. 자바는 다중상속을 허용하지 않기 때문에, Thread 클래스 외 다른 클래스를 상속 받을 수 없다.

결론:

  • Runnable 인터페이스 구현: Thread 클래스가 다른 클래스를 확장해야하거나, 익명클래스로 한 곳에서만 스레드 사용 
  • Thread 클래스 상속: 이외의 경우

Runnable 인터페이스 구현

  1. 임의의 클래스를 만들어 Runnable을 구현한다.
  2. run()의 메서드 바디에 실제 스레드가 수행할 코드를 작성한다.
  3. 위에서 구현한 객체를 생성 후, Thread 클래스의 인자로 전달하여 스레드를 생성한다.
  4. 실행
만약 예제코드와 같이 main 메서드에 실행문이 존재할 경우
main메서드의 메인 스레드, 인터페이스를 구현한 클래스에 의한 작업스레드가 동시에 병렬로 실행된다.
public class ThreadExample1 {
    public static void main(String[] args) {
        Runnable task1 = new ThreadTask1(); // 3) Runnable 인터페이스를 구현한 인스턴스 생성
        Thread thread1 = new Thread(task1); // 4) 위 객체를 인자로 전달하여 Thread 클래스를 인스턴스화 하여 스레드 생성

        // 작업 스레드를 실행시켜, run() 내부의 코드를 처리하도록 한다. 
        thread1.start();
        
        // 메인스레드에서 실행할 반복문 추가
        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

class ThreadTask1 implements Runnable { // 1) 인터페이스 구현
    public void run() {
        for (int i = 0; i < 100; i++) { // 2) 실행문 작성
            System.out.print("#");
        }
    }
}

//출력
@@@@@@@@@@@######@@@@@############################
@#########@@@@@@@@@@@@@@@@############@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@##@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@###########################################

Thread 상속

  1. Thread클래스를 상속하는 하위 클래스 생성
  2. run()메서드 오버라이딩하여 바디에 실행문 작성
  3. 상속받은 클래스의 객체 생성. 
  4. 실행
public class ThreadExample2 {
    public static void main(String[] args) {

        ThreadTask2 thread2 = new ThreadTask2();

        // 작업 스레드를 실행시켜, run() 내부의 코드를 처리하도록 합니다. 
        thread2.start();

        // 반복문 추가
        for (int i = 0; i < 100; i++) {
            System.out.print("@");
        }
    }
}

class ThreadTask2 extends Thread {
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.print("#");
        }
    }
}

'JAVA' 카테고리의 다른 글

[JAVA] JVM이란?  (0) 2023.07.18
[JAVA] Thread(2) 동기화  (0) 2023.07.18
[JAVA] Stream (3) 최종 연산  (0) 2023.07.17
[JAVA] Stream(2) 중간연산  (0) 2023.07.17
[JAVA] Stream(1) Stream 생성하기  (0) 2023.07.17
profile

Nulog

@Nuni0617

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!