ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이것이 자바다 | 12장 멀티 스레드
    JAVA/이것이 자바다 2022. 7. 23. 14:24

    12.1 멀티 스레드 개념

    멀티 프로세스: 서로 독립적 -> 오류가 발생해도 다른 프로세스에 영향 X

    멀티 스레드: 하나의 프로세스 내부에 생성 -> 하나의 스레드에 예외 발생 -> 프로세스 자체 종료될 수도 있음

     

    1. 메인 스레드

    메인 스레드는 필요에 따라 작업 스레드들을 만들어서 병렬로 코드 실행 가능

     

    12.2 작업 스레드 생성과 실행

    작업 스레드들이 객체로 생성되기 때문에 클래스 필요

    1. java.lang.Thread 클래스를 직접 객체화
    2. Thread를 상속해서 하위 클래스 생성

    1. Thread 클래스로부터 직접 생성

    :java.lang.Thread 클래스로부터 작업 스레드 객체를 직접 생성

    • Runnable 을 매개값으로 갖는 생성자를 호출
    • Runnable의 run() 메소드 재정의
    • Runnable 구현 객체 생성
    • 구현 객체를 매개값으로 해서 Thread 생성자를 호출
    Thread thread = new Thread(Runnable target);

    Runnable 은 인터페이스 타입임 => 구현 객체 만들어야 함

    Runnable에는 run() 메소드 하나가 정의되어 있음 => run() 재정의

    class Task implements Runnable {
        public void run() {
            스레드가 실행할 코드;
        }
    }

     

    <코드 절약>

    • Thread 생성자를 호출할 때 Runnable 익명 객체를 매개값으로 사용
    Thread thread = new Thread( new Runnable() {
        public void run() {
            스레드가 실행할 코드;
        }
    } );
    Thread thread = new Thread( () -> {
        스레드가 실행할 코드;
    } );

     

    작업 스레드는 start() 메소드를 호출해야만 실행됨

    thread.start;

     

    2. Thread 하위 클래스로부터 생성

    작업 스레드가 실행할 작업을 Runnable로 만들지 않고, Thread 하위 클래스로 작업 스레드를 정의하면서 작업 내용을 포함시킴

    Thread 클래스를 상속한 후 run 메소드를 재정의(overriding)해서 스레드가 실행할 코드를 작성하면 됨

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

     

    < 코드 절약 >

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

    이후 start() 메소드 호출

     

    12.3 스레드 우선순위

    멀티 스레드는 동시성 또는 병렬성으로 실행됨

     

    동시성: 멀티 작업을 하나의 코어에서 멀티 스레드가 번갈아가며 실행

    병렬성: 멀티 작업을 멀티 코어에서 개별 스레드를 동시에 실행

     

    스레드 스케줄링

    스레드의 개수가 코어 수보다 많을 경우, 스레드를 어떤 순서에 의해 동시성으로 실행할 것인가를 결정하는 것

     

    • 우선수위 방식
    • 순환할당 방식

    우선순위 방식:

        우선 순위가 높은 스레드가 높은 스레드가 실행 상태를 더 많이 가지도록 스케줄링하는 것

        코드로 제어 가능

     

    순환할당 방식:

        시간 할당량을 정해서 하나의 스레드를 정해진 시간만큼 실행하고 다시 다른 스레드를 실행

        코드로 제어 불가

     

    12.4 동기화 메소드와 동기화 블록

     

    임계 영역: 단 하나의 스레드만 실행할 수 있는 코드 영역

    동기화 메소드 & 동기화 블록: 임계 영역을 지정하기 위해 자바에서 제공

     

    스레드가 객체 내부의 동기화 메소드 또는 블록에 들어가면 즉시 객체에 잠금을 걸어 다른 스레드가 임계 영역 코드를 실행하지 못하게 함

     

    동기화 메소드 만드는 방법: 메소드 선언에 synchronized 키워드 붙이기

    public synchronized void method() {
        임계 영역;
    }

     

    12.5 스레드 상태

    스레드 객체를 생성하고, start() 메소드를 호출하면 곧바로 스레드가 실행되는 것 X

     

    스레드 객체 생성 → start() 실행 대기 상태 스레드 스케줄링으로 스레드 선택 run()  실행(스레드 스케줄링으로 다시 실행 대기 상태로 돌아갈 수 있음)  종료

     

    getState(): 스레드 상태에 따라서 Thread.State 열거 상수 리턴

     

    12.6 스레드 상태 제어

    1. 주어진 시간동안 일시 정지 (sleep())

    Thread.sleep(1000);

        ↪ 1초 동안 일시정지

     

    2. 다른 스레드에게 실행 양보 (yield())

    yield() 메소드를 호출한 스레드는 실행 대기 상태로 돌아가고 동일한 우선순위 또는 높은 우선순위를 갖는 다른 스레드가 실행 기회를 가질 수 있도록 함

    public void run() {
        while(true) {
                if(work) {
                    System.out.println("ThreadA 작업 내용");
                } else {
                    Thread.yield();
                }
            }
        }
    }

     

    3. 다른 스레드의 종료를 기다림 (join())

     

    sumThread가 종료할 때까지 메인 스레드를 일시 정지

    ``` 메인 스레드
    
    SumThread sumThread = new SumThread();
    sumThread.start();
    
    try {
        sumThread.join();
        } catch (InterruptedEsception e) {
        }
        
    ```

     

    4. 스레드 간 협업 (wait(), notify(), notifyAll())

    두 개의 스레드를 교대로 번갈아가며 실행할 경우 사용

    동기화 블록, 메소드에서만 사용 가능

     

    한 스레드가 작업을 완료하면 notify() 메소드를 호출 → 일시 정지 상태의 다른 스레드를 실행 대기 상태로 만들고, 자신은 wait() 메소드를 호출해서 일시정지 상태로 만듦

     

    notifyAll() : wait() 메소드에 의해 일시 정지된 모든 스레드들을 실행 대기 상태로 만듦

     

     

    5. 스레드의 안전한 종료 (interrupt())

     

    interrupt(): 스레드가 일시 정지 상태에 있을 때 InterruptException 예외를 발생시킴

    InterruptException 발생시, 예외 처리로 run() 메소드 정상 종료하게 됨

     

    12.7 데몬 스레드

    주 스레드의 작업을 돕는 보조적인 역할을 하는 스레드 -> 주 스레드가 종료되면 데몬 스레드는 자동 종료됨

     

    데몬 스레드 만드는 방법:

    주 스레드가 데몬이 될 스레드의 setDaemon(true)를 호출

    * start() 메소드 호출 전에 setDaemon(true)를 호출해야 함

     

     

     

     

     

     

     

     

Designed by Tistory.