자바의 정석 정리

자바의 정석 - 13.8 쓰레드 실행제어

ksb-dev 2022. 8. 29. 10:42

13.8.1 실행제어

  • 생성 → 실행대기 : start()
  • 실행대기 → 실행
  • 실행 → 소멸 : stop()
  • 실행 → 실행대기 : yield()
  • 실행 → 일시정지 : suspend(), sleep(), wait(), join(), I/O block
  • 일시정지 → 실행대기 : time-out, resume(), notify(), interrupt()
resume(), stop(), suspend()는 교착상태 문제 때문에 deprecated됨

13.8.2 sleep(long millis)

  • 일정시간동안 쓰레드 정지
  • 예외처리를 해 주어야함(메서드 생성시 편리함)
void delay(long millis){
    try{
        Thread.sleep(1, 500000);
    }catch(InterruptedException e){}
}

-sleep은 항상 현재 실행 중인 쓰레드에 동작을 하기 때문에원하는 것 처럼 동작을 안할 수 있음

class ThreadEx12_1 extends Thread {
    public void run() {
        for(int i=0; i<300; i++) 
            System.out.print("-");
        System.out.print("<<th1 종료>>");    
    }
}

class ThreadEx12_2 extends Thread {
    public void run() {
        for(int i=0; i<300; i++) 
            System.out.print("|");
        System.out.println("<<th2 종료>>");
    }
}

public class ThreadEx12 {
    public static void main(String[] args) {
        ThreadEx12_1 th1 = new ThreadEx12_1();    
        ThreadEx12_2 th2 = new ThreadEx12_2();
        th1.start();    // 쓰레드 시작
        th2.start();

        // sleep()을 사용하면 'InterruptedException'예외처리를 해줘야 함
        try {
                        // sleep()은 현재 실행 중인 쓰레드에 대해 작동하기 때문에 main쓰레드에 영향
            //th1.sleep(2000);    
            Thread.sleep(2000);
        } catch(InterruptedException e) {}    

        System.out.println("<<main 종료>>");
    }
}

13.8.3 interrupt()와 interrupted()

  • 쓰레드 작업 취소
  • interrupt : 작업 중지 요청
  • interrupted : 쓰레드의 상태
  • 메서드 종류
void interrupt() //interrupted상태변경
boolean isInterrupted() //interrupted상태 반환
static boolean interrupted() //interrupted상태 반환 후, false로 변경
import javax.swing.JOptionPane;

class ThreadEx13_1 extends Thread {
    public void run() {
        int i=10;

        // i가 0이 아니고 interrupted상태가 false가 아닐때까지 반복
        while(i!=0 && !isInterrupted()) {    
            System.out.println(i--);
            for(long x=0;x<2500000000L;x++);
        }
        System.out.println("카운트가 종료되었습니다.");
    }
}

public class ThreadEx13 {
    public static void main(String[] args) {
        ThreadEx13_1 th1 = new ThreadEx13_1();
        th1.start();    // 쓰레드 시작

        String input = JOptionPane.showInputDialog("아무 값이나 입력하세요");
        System.out.println("입력하신 값은 " + input + "입니다.");
        // 21,22행 실행 후, interrupted()실행
        th1.interrupt();// 쓰레드의 interrupted상태 -> true로 변경, 작업을 멈춤
        System.out.println("isInterrupted() : " + th1.isInterrupted());
  • 일시정지상태에 있는 쓰레드에 interrupt() 호출 시 실행 대기 상태로 바뀜

13.8.4 suspend(), resume(), stop()

  • 실행 → 일시정지 : suspend(), stop()

-일시정지 → 실행대기 : resume()

  • suspend()와 stop()은 deprecated됨

13.8.5 yield()

  • 남아있는 실행시간을 다른 쓰레드에 양보
Thread.yield();

13.8.6 join()

  • 작업을 멈추고 다른 쓰레드의 작업을 기다릴 때 사용
  • 파라미터에 시간 미 지정시 해당 쓰레드가 작업을 모두 마칠 때 까지 기다림
void join()
void join(long millis)
void join(long millis, int nanos)
  • 예외처리를 해 주어야 함(sleep과 달리 static이 아니여서 메소드 생성x)
try{
    th1.join();
} catch(InterruptedException e){}
class ThreadEx19 {
    static long startTime = 0;

    public static void main(String args[]) {
        ThreadEx19_1 th1 = new ThreadEx19_1();
        ThreadEx19_2 th2 = new ThreadEx19_2();

        th1.start();
        th2.start();
        startTime = System.currentTimeMillis();

        try {
            th1.join();    // main쓰레드가 th1의 작업이 끝날 때까지 기다린다.
            th2.join();    // main쓰레드가 th2의 작업이 끝날 때까지 기다린다.
        } catch(InterruptedException e) {}

        System.out.print("소요시간:" + (System.currentTimeMillis() - ThreadEx19.startTime));
    } // main
}

class ThreadEx19_1 extends Thread {
    public void run() {
        for(int i=0; i < 300; i++) {
            System.out.print(new String("-"));
        }
    } // run()
}

class ThreadEx19_2 extends Thread {
    public void run() {
        for(int i=0; i < 300; i++) {
            System.out.print(new String("|"));
        }
    } // run()
}