개발자꿈나무

쓰레드 - 실행제어 (sleep, join, yield) 본문

자바

쓰레드 - 실행제어 (sleep, join, yield)

망재이 2023. 1. 29. 13:16

01. 쓰레드의 상태

  1. 쓰레드를 생성하고 start()를 호출하면 바로 실행되는 것이 아니라 실행대기열에 저장되어 자신의 차례가 될 때까지 기다린다.
  2. 실행대기상태에 있다가 자기 순서가 되면 실행된다.
  3. 주어진 실행시간이 다 되거나 yield()를 만나면 다시 실행대기상태가 되고 다음 차례의 쓰레드가 실행된다.
  4. 실행 중에 suspend(), sleep(), wait(), join(), i/O block에 의해 일시정지 상태가 되기도 한다.
  5. 지정된 일시정지 시간이 다 되거나 notify(), resume(), interrupt()가 호출되면 일시정지 상태를 벗어나 다시 실행대기열에 저장된다.
  6. 실행을 모두 마치거나 stop()이 호출되면 실행 종료되며 쓰레드는 소멸된다.

02. 쓰레드의 실행제어

  • 효울적인 멀티쓰레드 프로그램을 만들기 위해서 다양한 실행제어문을 통해 정교한 스케줄링을 프로그래밍 해줘야 한다.
더보기
  • sleep()
  • 지정된 시간동안 쓰레드를 멈추게 해줌
  • 시간이 다 되거나 interrupt()가 호출되어 일시정지 상태를 벗어난 쓰레드는 InterruptedException이 발생되어 항상 try-catch문으로 예외처리를 해줘야 한다.(부를 때마다 처리 해주는 것이 번거로우므로, 메소드를 만드는 것도 좋은 방법)

 

static void sleep(long millis)

static void sleep(long millis, int nanos)

 

void delay(long millis) {

     try {

         Thread.sleep(millis);

     } catch(InterruptedException e) {}

}

public class SleepThread
{

	public static void main(String[] args)
	{
		Thread1 th1 = new Thread1();
		Thread0 th2 = new Thread0();
		th1.start();
		th2.start();
		
		try
		{
			Thread.sleep(2000);
		} catch (InterruptedException e)
		{
		}
		System.out.print("<<main 종료>>");
	}

}

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

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

//th2메소드가 종료된 후에 th2 main순으로 종료됨. sleep()메소드는 항상 현재 실행중인 쓰레드에 작동하기 때문에 
//main메소드를 실행하는 main쓰레드에서 영향을 받음

더보기
  • interrupt()
  • 진행 중인 쓰레드의 작업이 끝나기 전에 멈추라고 요청하는 실행문
  • InterruptedException 예외가 발생하며 쓰레드를 깨우므로 예외처리를 해줘야 정상 실행된다.
  • Thread의 interrupted()와 isInterrupted() 메소드는 interupted() 메소드 호출 여부를 리턴한다.

 

void interrupt() // 쓰레드의 interrupted상태를 false에서 true로 변경

boolean isInterrupted() // 쓰레드의 interrupted상태를 반환

static boolean interrupted() // 현재 쓰레드의 interrupted상태를 반환 후, false로 변경


더보기
  • join()
  • 자신이 하던 작업을 잠시 멈추고 다른 쓰레드가 지정된 시간동안 작업을 수행하도록 할 때 사용
  • 시간을 지정하지 않으면 해당 쓰레드가 작업을 모두 마칠 때까지 기다리게 된다.
  • 작업 중에 다른 쓰레드의 작업이 먼저 수행되어야할 필요가 있을 때 join()을 사용.
  • join()메소드도 interrupt()에 의해 대기상태에서 벗어날 수 있으므로, try-catch문으로 예외처리 해줘야함.

 

void join()

void join(long millis)

void join(long millis, int nanos)

 

  • yield()
  • 쓰레드 자신에게 주어진 실행시간을 다음 차례의 쓰레드에게 양보할 때 사용
public class JoinYieldThread
{
	static long startTime = 0;

	public static void main(String[] args)
	{
		Thread0 th1 = new Thread0();
		Thread1 th2 = new Thread1();
		th1.start();
		th2.start();
		startTime = System.currentTimeMillis();
		
		try
		{
			th1.join(); //main쓰레드가 th1의 작업이 끝날 때까지 기다린다.
			th2.join(); //main쓰레드가 th2의 작업이 끝날 때까지 기다린다.
		} catch (InterruptedException e)
		{
		}
		System.out.println("소요시간 : "+(System.currentTimeMillis()-JoinYieldThread.startTime));
	}

}

//main쓰레드에게 join()실행문을 주었기에 th1과 th2가 작업을 마칠 때까지 기다렸다가 소요시간을 출력할 수 있다.
728x90

'자바' 카테고리의 다른 글

람다식 - 함수형 인터페이스  (0) 2023.02.13
람다식 작성하기  (0) 2023.02.13
쓰레드 - 멀티쓰레드, 쓰레드 우선순위  (0) 2023.01.28
컬렉션 프레임워크 - TreeMap  (0) 2023.01.28
컬렉션 프레임워크 - HashMap  (0) 2023.01.28