minghxx.blog
  • 자바의 정석 148~157강 ch13 쓰레드
    2023년 10월 12일 12시 07분 49초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

    자바의 정석 기초편(2020최신)

    ch 13-1 프로세스와 쓰레드 

    1. 프로세스 process

    실행 중인 프로그램, 자원(메모리, CPU 등)과 쓰레드로 구성

     

    2. 쓰레드 Thread

    프로세스 내에서 실제 작업을 수행, 모든 프로세스는 최소한 하나의 쓰레드를 가지고 있음

    새로운 프로세스 생성보다 새로운 스레드 생성이 적은 비용

     

    3. 멀티스레드의 장단점

    장점 단점
    시스템 자원을 효율적으로 사용 가능
    사용자에 대한 응답성 향상
    코드 간결
    동기화 synchronization 주의
    교착상태가 발생하지 않도록 주의
    각 스레드가 효율적으로 고르게 실행될 수 있게 해야함(기아현상)

    ch 13-3~6 스레드의 구현과 실행

    1. 스레드 구현

    자바는 단일 상속만 지원, Thread 클래스를 상속받을경우 다른 클래스 상속이 어려워 인터페이스 구현방법이 더 유연

     

    ①Thread 클래스 상속

    class MyThread extends Thread {
    	public void run() { } // Thread클래스의 run()을 오버라이딩
    }
    
    MyThread t1 = new MyThread(); // 쓰레드 생성
    t1.start(); // 실행

     

    ②Runnable인터페이스 구현

    class MyThread2 implements Runnable {
    	public void run() { } // Runnable 인터페이스의 추상메서드 run() 구현
    }
    
    Runnable r = new MyThread2();
    Thread t2 = new Thread(r); // 쓰레드 생성
    t2.start(); // 실행

     

    2. 쓰레드 실행 start()

    스레드를 생성한 후 start()호출하면 실행 가능 상태

    OS 스케줄러가 실행순서를 결정

     

    3. run()과 start()

    start() 호출 → 새로운 호출 스택 생성되고 종료

    run() 호출 새로운 호출스택에서 실행

    서로 독립적으로 작업 수행 가능해짐


    ch 13-7~13 싱글 스레드와 멀티 스레드, 스레드의 I/O 블락킹

    1. main 쓰레드

    main 메서드의 코드를 수행하는 쓰레드

    사용자 쓰레드와 데몬 쓰레드(보조 쓰레드) 두 종류

    실행 중인 사용자 쓰레드가 하나도 없을 때 프로그램 종료

    main이 종료되더라도 사용자 쓰레드가 실행 중이면 프로그램 종료되지 않음

     

    2. 싱글 쓰레드

     

    3. 멀티 쓰레드

    스레드를 번갈아가며 실행하기 때문에(context switching) 싱글 스레드보다 시간이 조금 더 소요됨

     

    4. 쓰레드의 I/O blocking

    입출력시 작업 중단되는 현상

    싱글 스레드의 경우 I/O를 기다리는 동안 작업이 정지되지만 멀티 스레드의 경우 I/O를 기다리면서 다른 스레드가 작업을 실행한다.

     


    ch 13-14~17 쓰레드의 우선순위, 쓰레드 그룹

    1. 쓰레드의 우선순위

    작업의 중요도에 따라 쓰레드의 우선순위를 다르게 하여 특정 쓰레드가 더 많은 작업 시간을 갖게 할 수 있음

    1~10까지 설정 가능, 기본 우선순위는 5

    우선순위는 희망사항일 뿐 OS 스케줄러가 알아서 조정

     

    2. 쓰레드 그룹

    서로 관련된 쓰레드를 그룹으로 묶어서 다루기 위함

    모든 쓰레드는 하나의 쓰레드 그룹에 포함, 미지정시 main쓰레드 그룹에 속함

    자신을 생성한 쓰레드(부모쓰레드)의 그룹과 우선순위를 상속 받음

    쓰레드 그룹 메서드


    ch 13-18~21 데몬 쓰레드, 쓰레드의 상태

    1. 데몬 쓰레드

    인반 쓰레드의 작업을 돕는 보조적인 역할 수행

    일반 쓰레드가 모두 종료되면 자동으로 종료

    가비지 컬렉터, 자동 저장, 화면 자동 갱신 등에 사용

    무한루프와 조건문을 이용해 실행 후 대기하다가 특정 조건이 만족되면 작업을 수행하고 다시 대기하도록 작성

    데몬 쓰레드 작성

    class Ex13_7 implements Runnable  {
    	static boolean autoSave = false;
    
    	public static void main(String[] args) {
    		Thread t = new Thread(new Ex13_7());
    		t.setDaemon(true);	// start()전에 설정
    		// 데몬으로 지정하지 않으면 종료되지 않는다. 
    		t.start();
    
    		for(int i=1; i <= 10; i++) {
    			try{
    				Thread.sleep(1000);
    			} catch(InterruptedException e) {}
    			System.out.println(i);
    
    			if(i==5) autoSave = true;
    		}
    
    		System.out.println("프로그램을 종료합니다.");
    	} // main 쓰레드
    	// 실행 중인 일반 쓰레드가 없으면 데몬쓰레드도 종료
    
    	public void run() {
    		while(true) { // 무한루프
    			try { 
    				Thread.sleep(3 * 1000); // 3초마다
    			} catch(InterruptedException e) {}
    
    			// autoSave의 값이 true면 autoSave()를 호출
    			if(autoSave) autoSave();
    		}
    	}
    
    	public void autoSave() {
    		System.out.println("작업파일이 자동저장 되었습니다.");
    	}
    }

     

    2. 쓰레드 상태

    NEW 쓰레드가 생성되고 start() 미호출 상태
    RUNNABLE 실행 중 또는 실행 가능한 상태
    BLOCKED 동기화 블럭에 의해서 일시정지된 상태(lock이 풀릴 때까지 기다리는 상태)
    WAITING
    TIMED_WAITING
    쓰레드의 작업이 종료되지 않았지만 실행가능하지 않는 일시정지 상태
    TIMED_WAITING 일시정지 시간 지정
    TERMINATED 쓰레드의 작업 종료

     

    3. 쓰레드의 실행 제어

    실행을 제어할 수 있는 메서드 제공

    static void sleep(long millis)
    static void sleep(long millis, int nanos)
    지정된 시간동안 쓰레드 일시정지, 지정 시간이 지나면 자동으로 실행대기 상태
    쓰레드 자기 자신에게만 호출 가능
    void join()
    void join(long millis)
    void join(long millis, int nanos)
    지정된 시간동안 쓰레드 실행, 지정 시간이 지나거나 작업이 종료되면 join()을 호출한 쓰레드로 다시 돌아와 실행함
    void interrupt() sleep()이나 join()에 의해 일시정지상태인 쓰레드를 깨워 실행대기 상태로 변경
    Interrupt Exception 발생하여 일시정지 상태 벗어남
    void stop() 쓰레드 즉시 종료
    void suspend() 쓰레드 일시정지, resume() 호출시 다시 실행대기상태로 변함
    void resume() suspend()에 의해 일지정시상태에 있는 쓰레드 실행대기상태로 변환
    static void yield() 실행 중 자기에게 주어진 실행시간을 다른 쓰레드에게 양보하고 자신은 실행대기상태
    쓰레드 자기 자신에게만 호출가능

    ch 13-22~25 sleep(), interrupt()

    1. sleep()

    현재 쓰레드를 지정된 시간동안 멈추게 함

    자기 자신에게만 호출 가능한 메서드  특정 쓰레드 지정해 멈추게하는 것 불가능

    시간이 종료되거나 intrrupt()메서드 호출하면 실행대기 상태로 변경

    실행대기 상태로 변경될 때 예외가 발생되는 메서드 → InterruptException 예외 처리 필요

     

    2. interrupt()

    대기상태WAITING인 쓰레드를 실행대기RUNNABLE 상태로 만듦

    inturrpt() interrupted 상태를 false → true
    isInterrupted() interrupted 상태 반환
    interrupted() isInterrupted() + false로 초기화

    ch 13-26~27 suspend(), resume(), stop()

     

    suspend() 쓰레드 일시정지

    resume() suspend()에 의해 일시정지된 쓰레드를 실행대기 상태로 만듦

    stop() 쓰레드 즉시 종료

    교착상태 가능성↑ deprecated 되었음


    ch 13-28~29 join(), yield()

    1. join()

    지정 시간동안 특정 쓰레드가 작업하는 것을 기다림

    예외가 발생되는 메서드 → InterruptException 예외 처리 필요

     

    2. yield()

    남은 시간을 다음 쓰레드에게 양보하고 자신은 실행대기 상태로 변경

    자기 자신에게만 호출 가능한 메서드 

    yield()와 interrupt()를 적절히 사용하면 응답성과 효율을 높일 수 있음 → busy-waiting을 줄일 수 있음


    ch 13-30~33 쓰레드의 동기화

    1. 쓰레드의 동기화

    멀티 쓰레드 프로세스에서 다른 쓰레드의 작업에 영향 미칠 수 있음

    진행중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 동기화 필요

    임계영역 : 간섭받지 않아야 하는 문장을 설정, 락을 얻은 단 하나의 쓰레드만 출입가능(1객체 락 1개)

     

    2. synchronized로 임계영역 설정하는 방법

    ① 메서드 전체 임계영역으로 지정

    public synchronized void calcSum() { }

    ② 특정 영역 임계영역으로 지정

    synchronized(객체 참조변수) { }

    ch 13-34~36 wait(), notify()

    동기화 효율을 높이기 위해 wait(), notify() 사용

    Object 클래스에 정의, 동기화 블록 내에서만 사용 가능

    wait() 객체의 lock을 풀고 쓰레드를 해당 객체의 waiting pool에 넣음
    notify() waiting pool에서 대기중인 쓰레드 중 하나 깨움
    notifyAll() waiting pool에서 대기중인 모든 쓰레드 깨움

     

    728x90
    댓글