Java/객체지향

[객체지향][쓰레드/thread] - sleep(), interrupt()

얄루몬 2022. 3. 2. 19:44

https://youtu.be/cDUcF1QD4Gw?list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp 

📖본 포스팅은 '자바의 정석 - 남궁성 저자' 님의 책과 유튜브 강의를 보고 작성되었습니다.


쓰레드의 실행을 제어하는 메서드 sleep( ), interrupt()

 

[sleep( )]

    • 현재 쓰레드를 지정된 시간동안 멈추게 한다. (잠자게 한다.)
static void sleep(long millis) // 천분의 일초 단위
static void sleep(long millis, int nanos) //천분의 일초 + 나노초
  • sleep()은 static 메서드로 항상 현재 쓰레드에 동작하게 한다.
    • static = 자기 자신에게만 동작
    • 양보의 경우도 자신이 양보는 가능하지만 다른 쓰레드가 양보하는 것을 하라곤 할 수 없다.
  • sleep() 메서드는 예외를 발생시킬 수 있어서 예외처리를 해주어야 한다. (InterruptedException이 발생하면 깨어난다.)
    • 이런 것이 귀찮아서 sleep()을 포함한 메소드를 만들어서 사용한다.
  • 특정 쓰레드를 지정해서 멈추게 하는 것은 불가능하다.
    • th1.sleep() XXX 
    • Thread.sleep() OOO
    • static 메소드이기 때문이다!(자기 자신만)

 

 

[실습 코드]

package javaStandard;

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


class ThreadEx8_1 extends Thread {
	public void run() {
		for(int i = 0 ; i < 300 ; i ++)
			System.out.print("-");
		System.out.print("<<th1 종료>>");
	}
}
class ThreadEx8_2 extends Thread {
	public void run() {
		for(int i = 0 ; i < 300 ; i ++)
			System.out.print("|");
		System.out.print("<<th2 종료>>");
	}
}
  • 이 경우 th1.sleep( )이라고 해도 main쓰레드를 재우는 것이 때문에 2초 뒤에 끝났다는 문구가 나온다.
[출력값]
----------------------------------------------------------------------------------------------------------------------------------------------|||||||||||||||||||||||||||||||||||||||||||||||-------|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||-------------------<<th2 종료>>------------------------------------------------------------------------------------------------------------------------------------<<th1 종료>><<main 종료>>

 

[따로 sleep()을 넣어 메소드로 사용하는 경우]

package javaStandard;

public class Java13_8 {
	public static void main(String[] args) {
		ThreadEx8_1 th1 = new ThreadEx8_1();
		ThreadEx8_2 th2 = new ThreadEx8_2();
		
		th1.start();
		th2.start();
		
		
		
		System.out.print("<<main 종료>>");
		
	}
	
	static void delay(long millis) {
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {}
	}
}



class ThreadEx8_1 extends Thread {
	public void run() {
		for(int i = 0 ; i < 300 ; i ++)
			System.out.print("-");
		System.out.print("<<th1 종료>>");
	}
}
class ThreadEx8_2 extends Thread {
	public void run() {
		for(int i = 0 ; i < 300 ; i ++)
			System.out.print("|");
		System.out.print("<<th2 종료>>");
	}
}
  • 이때는 따로 예외처리를 해주지 않아도 메소드 내에서 이미 계속 예외처리가 된 채 있기 때문에 편리하게 사용할 수 있다.
  • 원하는 곳에 delay( ) 메소드를 사용하고 싶은 쓰레드 부분에 사용하면 된다.

 

 

[interrupt( )]

  • 대기 상태(WAITING)인 쓰레드를 실행대기 상태(RUNNABLE)로 만든다.
    • 대기 상태(WAITING) - 작업이 중단
      • sleep( )
      • join( )
      • wait( )
void interrupt() //쓰레드의 interrupted 상태를 false에서 true로 변경
boolean isInterrupted() //쓰레드의 interrupted 상태를 변화 / 얘는 초기화 안 해줌
static boolean interrupted() //현재 쓰레드의 interrupted 상태를 알려주고, false로 초기화

 

 

[실습]

package javaStandard;

import javax.swing.JOptionPane;

public class Java13_9 {

	public static void main(String[] args) {
		ThreadEx9_1 th1 = new ThreadEx9_1();
		th1.start();
		System.out.println("isInterrupted(): "+ th1.isInterrupted()); //false
		
		String input = JOptionPane.showInputDialog("아무 값이나 입력해주세요.");
		System.out.println("입력하신 값은 "+ input + "입니다.");
		
		th1.interrupt(); // interrupt()를 호출하면 interrupted 상태가 true가 된다.
		System.out.println("isInterrupted(): "+ th1.isInterrupted()); //true
		System.out.println("isInterrupted(): "+ th1.isInterrupted());//true

		
	}

}
class ThreadEx9_1 extends Thread{
	public void run() {
		int i = 10;
		
		while(i!=0 &&!isInterrupted()) {
			System.out.println(i--);
			for(long x=0; x<2500000000L; x++); //시간 지연
		}
		System.out.println("카운트가 종료되었습니다.");
	}
}
  • interrupted()의 경우엔 static 함수로 본인이 true인지 false인지 여부를 확인 함.