스레드(Thread) (미완)

귀찮Lee·2022년 5월 22일
0

Java

목록 보기
13/15

◎ 스레드(Thread)

  • 스레드(Thread)

    • 하나의 스레드는 하나의 코드 실행 흐름
    • 한 프로세스 내에 스레드가 두 개라면 두 개의 코드 실행 흐름이 생김
  • 멀티 스레드(Multi-Thread)

    • 애플리케이션 내부에서의 두 가지 이상의 작업을 동시에 처리 (어플리케이션 내 멀티 테스킹)
    • 사용 예시
      • 대용량 데이터의 처리시간을 줄이기 위해 데이터를 분할해서 병렬로 처리
      • UI를 가지고 있는 애플리케이션에서 네트워크 통신을 하기 위해 사용
      • 다수 클라이언트의 요청을 처리하는 서버를 개발
  • 메인 스레드(main thread)
    • 모든 자바 애플리케이션은 메인스레드(main thread)가 main() 메서드를 실행
    • 메인 스레드는 필요에 따라 작업 스레드들을 만들어서 동시에 코드를 실행할 수 있다.
    • 싱글 스레드 애플리케이션에서는 메인 스레드가 종료하면 프로세스도 종료됨. 하지만 멀티 스레드 애플리케이션에서는 실행 중인 스레드가 하나라도 있다면 프로세스는 종료 되지 않는다.

◎ Thread 생성과 실행

  • Thread 생성과 실행

    • 멀티 스레드로 실행하는 애플리케이션을 개발하려면 먼저 몇 개의 작업을 동시에 실행할지 결정하고 각 작업별로 스레드를 생성해야 한다.
    • 메인 작업 이외에 추가적인 병렬 작업의 수만큼 스레드를 생성하면 된다. (java에는 반드시 main 스레드가 존재)
    • 자바 스레드 생성 방법
      • 작업 스레드도 객체로 생성되기 때문에 클래스가 필요
      • java.lang.Thread 클래스를 직접 객체화 해서 생성 가능
      • Thread를 상속해서 하위 클래스를 만들어 생성할 수도 있다.
  • Thread 클래스로부터 직접 생성

    1. 작업 스레드 객체를 직접 생성하려면 Runnable을 매개변수로 갖는 생성자를 호출
    • Runnable (Interface)
      • 작업 스레드가 실행할 수 있는 코드를 가지고 있는 객체라는 의미로 붙여진 이름
      • 구현 클래스는 run()을 재정의해서 작업 스레드가 실행할 코드를 작성해야 한다.
      • 작업 내용을 가지고 있는 객체이지 실제 스레드는 아니다.
    1. Runnable 구현 객체를 생성한 후, 이것을 매개값으로 해서 Thread 생성자를 호출하면 비로소 작업 스레드가 생성
    2. start() 메서드를 호출하여 실행 (작업 스레드가 생성된 즉시 실행되지는 않는다.)
    public class threadCreateMethod {
        public static void main(String[] args) throws InterruptedException {
            // Runnable 구현한 객체 생성, 
            Runnable task = new Task();
            // Runnable 객체를 매개로 해서 thread 생성
            Thread thread = new Thread(task);
            // Runnable 익명 객체를 매개변수로 사용할 수 있습니다.
            Thread anonymousThread = new Thread(new Runnable() {
                public void run() {
                    System.out.println("Run in AnonymousThread");
                }
            });
            
            thread.start(); // 스레드 시작
            anonymousThread.start();
            
            for (int i=0; i<100; i++){
                Thread.sleep(250);
                System.out.println("Run in MainThread");
            }
        }
    }
    
    class Task implements Runnable {
        public void run() {
            for (int i=0; i<100; i++){
                try {
                    Thread.sleep(250);;
                } catch (InterruptedException e) {}
                System.out.println("Run in Thread");
            }
        }
    }
    // 출력값이 마구잡이로 나옴
  • Thread 하위 클래스로부터 생성

    • Thread의 하위 클래스로 작업 스레드를 정의하면서 작업 내용을 포함시킬 수도 있다.
    • Class 생성방법 : Thread 클래스를 상속한 후 run 메서드를 재정의(overriding)해서 스레드가 실행할 코드를 작성하면 된다.
    • 객체 생성 방법 : 일반적인 객체를 생성하는 방법과 동일
    class WorkerThread extends Thread {
        @Override
        public void run() {
            // 실행할 코드 ....
        }
    }
    
    public class threadCreateMethod {
        public static void main(String[] args)  {
    
            Thread thread = new WorkerThread();
            thread.start();
    
        }
    }
  • 스레드의 이름 (추가 필요)

    thread.setName("스레드 이름"); // 스레드 이름 설정
    thread.getName(); // 스레드 이름 가져오기
    
    Thread thread = Thread.currentThread();

◎ Thread 동기화

  • 동기화 메서드와 동기화 블록

    • 멀티 스레드 프로그램에서는 스레드들이 객체를 공유해서 작업해야 하는 경우, 스레드가 사용 중인 객체를 다른 스레드가 변경할 수 없도록 하려면 스레드 작업이 끝날 때까지 객체에 잠금을 걸어서 다른 스레드가 사용할 수 없도록 해야한다.

    • 임계 영역 : 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역

      • 자바는 임계 영역을 지정하기 위해서 동기화 메서드와 동기화 블록을 제공
      • 스레드가 객체 내부 임계 영역에 들어가면 즉시 객체에 잠금을 걸어 다른 스레드가 임계 영역 코드를 실행하지 못하도록 해야한다.
    • 동기화 메서드를 만드는 방법

      • 메서드 선언에 synchronized 키워드를 붙이면 된다.
      • 인스턴스와 정적 메서드 어디든 붙일 수 있다.

◎ Thread 상태

  • 스레드의 상태

    • start() 메서드를 호출시

      1. 실행 대기 상태 : 아직 스케줄링이 되지 않아서 실행을 기다리고 있는 상태
      2. 스레드 스케줄링으로 선택되면 스레드가 CPU를 점유하고 run( ) 메서드를 실행
    • 메서드 실행시

      • 메서드를 모두 실행하기 전에 스레드 스케줄링에 의해 다시 실행 대기 상태로 돌아갈 수 있습니다. (그리고 다른 스레드가 선택되어 실행함)
      • 실행 대기 상태와 실행 상태를 번갈아 가면서 자신의 run() 메서드를 조금씩 실행
      • run() 메서드가 종료되면, 더 이상 실행할 코드가 없기 때문에 스레드의 실행 은 멈춤 (종료 상태)
    • 메서드 실행 (일부 경우)

      • 실행 상태에서 실행 대기 상태로 가지 않고, 일시 정지 상태로 가기도 함
      • 일시 정지 상태: 스레드가 실행할 수 없는 상태
      • 다시 실행 상태로 가기 위해서는 일시 정지 상태에서 실행 대기 상태로 가야함
  • 스레드의 상태 종류

    상태열거 상수설명
    객체 생성NEW스레드 객체 생성, 아직 start() 메서드가 호출되지 않은 상태
    실행 대기RUNNABLE실행 상태로 언제든지 갈 수 있는 상태
    일시정지BLOCKED사용하고자 하는 객체의 락이 풀릴때까지 기다리는 상태
    일시정지WAITING다른 스레드가 통지할 때까지 기다리는 상태
    일시정지TIMED_WAITING주어진 시간동안 기다리는 상태 -> sleep(시간)
    종료TERMINATED실행을 마친 상태
    • 스레드의 상태 예시 :
      NEW → RUNNABLE → TIMED_WAITING → RUNNABLE → TERMINATED

◎ Thread 상태 제어

profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!

0개의 댓글