Backend

<Backend> Java / Thread (1)

이게왜 2023. 11. 9. 17:20

https://rezerocodinglife.tistory.com/22

 

Start <명품JAVA> ArrayList

명품자바의 예제문제, 실습문제를 풀며 공부해 나갑니다. 목표는 Collection, Generic, Comparable, Comparator, Iterable, Iterator, Stream, Lambda Expression등을 공부하여 이를 활용한 몬테카를로 시뮬레이션 미니 프

rezerocodinglife.tistory.com

공부를 시작하며 작성한 글 입니다. 공부하며 사용한 자료들이 있으니 참고하시면 좋겠습니다.


이번에는 Thread를 아주 조금 공부하였습니다.

(몬테카를로 시뮬레이션, 데이터베이스 과제에 밀려 공부진도가 더디네요..ㅠ)

프로세스(process)란?

프로세스(process)란 단순히 실행 중인 프로그램(program)이라고 할 수 있습니다.

즉, 사용자가 작성한 프로그램이 운영체제에 의해 메모리 공간을 할당받아 실행 중인 것을 말합니다.

이러한 프로세스는 프로그램에 사용되는 데이터와 메모리 등의 자원 그리고 스레드로 구성됩니다.

스레드(thread)란?

스레드(thread)란 프로세스(process) 내에서 실제로 작업을 수행하는 주체를 의미합니다.

모든 프로세스에는 한 개 이상의 스레드가 존재하여 작업을 수행합니다.

또한, 두 개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스(multi-threaded process)라고 합니다.

(출처: https://www.tcpschool.com/java/java_thread_concept)


< Thread의 구현과 실행 >

Thread를 구현하는 방법은 2가지 입니다.

  1. Thread Class를 extends 한다.
  2. Runnable Interface를 implement 한다.
제가 공부하고 이해한 내용으로는
Runnable Interface를 implement 하는 방법이 더욱 좋은 방법입니다.
왜냐하면 Thread Class를 extends 하여 Thread를 구현하면 다른 Class를 extends 할 수 없어 설계의 유연성이 떨어집니다.
(Java는 다중 상속을 지원하지 않습니다.)

1. Thread Class extend

<구현>

class MyThread extends Thread{  // Thread Class의 run()을 overriding
    public void run(){
        /* 작업내용 */       
    }
}

 

<실행>

MyThread t1 = new MyThread();
t1.start();

2. Runnable Interface implement

※ Interface를 상속받으면 다른 Class를 상속받을 수 있어 더욱 유연하게 사용 가능합니다.

 

< 구현 >

class MyThread implement Runnable{ //Runnable interface의 추상메서드 run()을 구현
    public void run(){
        /* 작업내용 */       
    }
}

 

< 실행 >

Runnable r = new MyThread2();
Thread t2 = new Thread(r);
// Thread t2 = new Thread(new MyThread2());
t2.start();

< start()와 run() >

  • main 메서드에서 run()을 호출하는 것은 스레드를 실행하는 게 아니라, 단순히 클래스에 선언된 메서드를 호출하는 것이다.
  • Thread 실행은 반드시 start() 이다.
package self_Thread;

public class Ex13_1 {

    public static void main(String[] args) {
        ThreadEx1_1 t1 = new ThreadEx1_1();
        Thread t2 = new Thread(new Thread1_2());

        t1.start();
        t2.start();
//        t1.run();
//        t2.run();
    }
}

class ThreadEx1_1 extends Thread {
    public void run() {
        for (int i = 0; i < 500; i++) {
            System.out.println(1);
        }
    }
}

class Thread1_2 implements Runnable {
    public void run() {
        for (int i = 0; i < 500; i++) {
            System.out.println(0);
        }
    }
}

 

Thread를 사용하여 출력했기 때문에 '1'과 '0'이 순서 없이 출력된다.

 

Thread가 실행되는 순서는 OS의 Scheduler가 (우선순위 부여) 관리합니다.

위 코드를 예시로 설명한다면,

OS의 Scheduler가 2개의 Thread t1, t2 중 우선순위를 부여해 Thread를 실행합니다.
만약 t1의 우선순위가 높다고 판단하면 t1이 실행됩니다.
t1이 실행되는 와중에도 Scheduler는 t1과 t2의 우선순위를 계속 비교합니다.
만약 t2의 우선순위가 t1의 우선순위보다 높다고 판단하면 t2가 실행됩니다.
(java 에서 Thread의 우선순위는 사용자가 정할 수 있다.)

 

이렇게 Thread나 Process를 교환하는 행위를 'Context Switching'이라고 합니다.

(출처 : https://javafactory.tistory.com/1528)


< Thread 종류 >

  • 사용자 스레드 (User Thread)
  • 데몬 스레드 (Daemon Thread)

"실행 중인 사용자 스레드가 하나도 없을 때 프로그램은 종료된다."
      즉 모든 User Thread가 종료되어야 프로그램이 종료된다.


앞으로 배워야 할 Thread 내용이 많지만 열심히 공부해 보겠습니다!