[Java] Thread

이지현·2023년 4월 10일
0

Java

목록 보기
32/46
post-thumbnail

✔️ Thread

1. Thread란?

  • 프로세스(공장) + 스레드(일꾼)
  • 프로세스 내부 작업의 흐름 또는 단위
  • 한 프로세스 내부에 적어도 하나 존재함

2. Thread 구현 방법

1) Thread 클래스 상속받기
2) Runnable 인터페이스 구현하기

public class Thread1 {
    public static void main(String[] args) {
        Thread1_1 t1 = new Thread1_1();

        Runnable r = new Thread1_2();
        Thread t2 = new Thread(r);

        t1.start(); // 스레드 t1 실행
        t2.start(); // 스레드 t2 실행
    }
}

class Thread1_1 extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            // Thread 클래스 메서드 직접 호출 가능
            System.out.println(getName());
        }
    }
}

class Thread1_2 implements Runnable {
    @Override
    public void run() {
        for(int i = 0; i < 5; i++) {
            // Runnable을 구현하면 Thread 클래스의 currentThread()를 호출하여
            // Thread에 대한 참조를 얻어와서 호출해야 함
            System.out.println(Thread.currentThread().getName());
        }
    }
}

실행결과

Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0

💡 start()가 호출되었다고 바로 실행되는 것이 아님, 일단 실행 대기 상태에 있다가 자신의 차례가 되어야 실행 상태가 됨
💡 하나의 스레드에 대해 start()는 한 번만 호출될 수 있음(두 번 실행 시 예외 발생)

3. start()와 run()

  • 메인 메서드에서 run()을 호출하는 것은 생성된 스레드를 실행시키는 것이 아니라 단순히 클래스에 선언된 메서드를 호출하는 것, 실행 중인 사용자 스레드가 없을 때 프로그램은 종료됨
@ main 메서드에서 run()을 호출하는 경우의 call stack
  |        |
  ----------
  |run     |
  ----------
  |main    |
  ----------

@ main 매서드에서 start()를 호출하는 경우
 #step 1.
  |        |
  ----------
  |start   |
  ----------
  |main    |
  ----------
 #step 2.
  |        |     |        | 
  ----------     |        |
  |start   |     |        |
  ----------     |        |
  |main    |     |        |
  ----------     ----------  
 #step 3. 
  |        |     |        | 
  ----------     |        |
  |start   |     |        |
  ----------     ----------
  |main    |     |run     |
  ----------     ----------
 #step 4.
  |        |     |        |
  |        |     |        |
  ----------     ----------
  |main    |     |run     |
  ----------     ----------
 #step 5. 
  |        |     |        |
  |        |     |        |
  |        |     ----------
  |        |     |run     |
  ----------     ----------

4. Multi Thread

  • 프로세스(공장) + 스레드(일꾼들)
  • 여러 스레드가 같은 프로세스 내에서 자원을 공유하면서 작업하기 때문에
    동기화교착 상태 같은 문제들을 고려하며 프로그래밍 해야 함
    💡 일정 메모리 영역을 공유하기 때문에 동일한 프로세스 내부의 스레드 간 문맥 전환을 할 경우가 프로세스끼리 문맥 전환을 할 때보다 빠름(상대적으로 스위치 해야 할 메모리 영역이 적기 때문임)

5. Single Thread와 Multi Thread의 차이

  • 한 개의 스레드로 두 개의 작업을 수행하는 경우 - concurrent:병행
| A 작업 | B 작업 |
  • 두 개의 스레드로 두 개의 작업을 수행하는 경우 - parallel:병렬
| A | B | A | B | A | B | A | B | A | B | A | B |

💡 싱글 코어에서 단순히 CPU만 사용하는 계산 작업이라면 Single Thread가 더 효율적임
💡 두 개의 스레드가 서로 다른 자원을 사용하는 작업의 경우 Multi Thread가 더 효율적임

6. Thread group

  • 보안상의 이유로 도입된 개념
  • 자신이 속한 스레드 그룹이나 하위 스레드 그룹은 변경할 수 있지만 다른 스레드 그룹의 스레드를 변경할 수 없음
Thread(ThreadGroup group, String name);
Thread(ThreadGroup group, Runnable target);
Thread(ThreadGroup group, Runnable target, String name);

7. Demon Thread

  • 다른 일반 스레드의 작업을 돕는 보조적인 역할을 수행

8. interrupt()와 interrupted()

  • 진행 중인 스레드의 작업이 끝나기 전에 취소시켜야 할 때가 있는 경우 사용
void interrupt(); // 스레드의 interrupted 상태를 false에서 true로 변경
boolean isInterrupted(); // 스레드의 interrupted 상태를 변환
static boolean isInterrupted(); // 현재 스레드의 interrupted 상태를 알려주고 false로 초기화

9. suspend(), resume(), stop()

  • suspend() : sleep()처럼 스레드를 멈추게 함 - Deprecated
  • resume() : suspend()에 의해 정지된 스레드는 resume()을 호출해야 다시 실행 대기 상태가 됨
  • stop() : 호출되는 즉시 스레드가 종료됨 - Deprecated

10. yeild()

  • 다른 스레드에게 양보함
  • 예를 들어 스케줄러에 의해 1초 실행시간을 할당받은 스레드가 0.5초동안 작업한 상태에서 yeild를 호출하게 되면, 바로 실행 대기 상태가 됨
    💡 yeild()와 interrupt()를 적절히 사용하면 프로그램의 응답성을 높이고 보다 효율적인 실행이 가능함

11. join()

  • 스레드 자신이 하던 작업을 멈추고 다른 스레드가 지정된 시간 동안 작업을 수행하도록 함
  • join()도 sleep()처럼 interrupt()에 의해 대기 상태에서 벗어날 수 있음
  • try-catch문으로 감싸야 함
  • sleep()과 다른 점은 특정 스레드에 대해 동작하므로 static 메서드가 아님

위 내용은 다음 블로그를 참고하였습니다.

profile
2023.09 ~ 티스토리 이전 / 2024.04 ~ 깃허브 블로그 이전

0개의 댓글