본문 바로가기
JAVA공부/2-쓰레드

쓰레드 제어문(1)

by 으노으뇨 2021. 10. 13.
728x90
반응형
SMALL

Sleep()

-현재 쓰레드를 지정된 시간동안 멈추게 한다.

static void sleep(long millis);
static void sleep(long millis, int nanos);

-static 메서드인 특성상 자기 자신만 제어할 수있다. 다른 쓰레드를 제어할 순없다. 

매개변수 내에 잠잘 시간을 정해준다.

밀리세컨드(3초  = 3000밀리세컨드)와 나노세컨드의 시간단위로 세밀하게 값을 지정할 수 있지만

어느정도 오차가 발생할 수 있다.

try{
Thread.sleep(1, 500000);
}catch(InterruptedException e){}

sleep()메서드는 예외를 발생시킬수 있으므로 예외문과 함께 다닌다.

Exception 클래스의 자손인 InterruptedException이기 때문에 예외 필수처리로 처리해주어야 한다.

sleep를 깨우는 방법은 시간을 정해주거나, 중간에 Interrupted 되던가 이다.

즉 시간이 다되던가, 누군가 깨워주어야한다. 여기서 아무런 예외가 발생하지 않으면 그 시간그대로 깨게되어 진행하게된다.

그런데 자는 동안 누군가 깨운다면 throw new InterruptedException으로 예외가 발생하게 된다. - 예외를 활용해서 깨우는 것이다.

- 문제가 생겨서 메서드가 깨는게 아니라, 잠자는 상태를 벗어나게 해주기 위해 예외를 응용한것이다.

그래서 catch블록에는 아무것도 없는게 정상이다. 물론 그사이에 System.out.println("은호가 꺠움"); 이렇게 해주는경우도 있곘지만 말이다.

그런데 매번 예외처리 하기 귀찮을 것이다. 그래서 그것에 대해서 또다른 매서드를 이용하는 것이다.

void delay(long millis){
try{
Thread.sleep(millis);
}
catch(interruptedException e){}
}

 delay라는 메서드를 만들어서 예외문을 한번에 묶어준다. 그래서 나중에 그 이 코드를  쉽게 활용 할수 있다.
- delay(15) 

그래서 대부분 sleep()을 매번 예외처리하면서 쓰기 귀찮아서 이렇게 메서드를 따로 만들어서 사용해서 코드를 줄이고 깔끔하게 만들어 줄 수 있겠다.

다시 한번 강조하지만 특정쓰레드를 지정해서 멈추게 하는것은 불가능하다.

//Tread2 th2
void delay(long millis){
try{
th1.sleep(millis); //th2에서 th1을 재우려한다 이럼안된다.
}
catch(interruptedException e){}
}

예제를 통해 조금 자세히 알아보자

package ch13.Thread;

public class ThreadEx12 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ThreadEx12_1 t1 = new ThreadEx12_1();
		ThreadEx12_2 t2 = new ThreadEx12_2();
		t1.start();
		t2.start();
		try {
			t1.sleep(2000);
		} catch (InterruptedException e) {

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

}

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

	}
}

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

똑같이 하나는 괄호짝대기, 세로짝대기 이렇게 출력하도록 하는것이다.

중간에 쓰레드 1을 2초동안 잠자게 하랴고 한것이다. 

그런데 쓰레드 1이 맨뒤에 종료 되었다고 나타나지 않고 main이 맨마지막에 종료되었다고 한다.

이것은 앞서 말한것처럼 쓰레드 클래스에서 제어가 가능하지 메인 쓰레드에서 t1으로 제어를 하려해도 결국 메인쓰레드가 제어되는것이다. 

왜나하면

 public static native void sleep(long millis) throws InterruptedException;

의 속성때문이다. 

그래서 t1을 멈추게하고싶으면 t1의 쓰레드 클래스에 sleep()을 넣어 주어서 재워야한다.

그래서 헷갈리거나 오해를 사지않도록 

이렇게쓰레드로 작성해 주어야한다.(쓰레드 클래스나 생성자 이름이 아닌!)

그리고 마지막에 예외처리 메서드를 만드는걸 실습해보자

		delay(2 * 1000);
	}

	static void delay(long millis) {
		try {
			Thread.sleep(millis);

		} catch (InterruptedException e) {

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

로 수정한뒤 실행하면 결과도 동일하게 얻을 수 있다.

 

728x90
반응형
LIST

'JAVA공부 > 2-쓰레드' 카테고리의 다른 글

쓰레드 제어문(3)  (0) 2021.10.14
쓰레드 제어문(2)  (0) 2021.10.13
쓰레드 제어문(1)  (0) 2021.10.13
데몬 쓰레드와 쓰레드의 상태(실행제어)  (0) 2021.10.12
쓰레드의 우선순위, 그룹  (0) 2021.10.12

댓글