관리 메뉴

나구리의 개발공부기록

자바의 정석 기초편 ch13 - 14 ~ 21 [쓰레드의우선순위,쓰레드그룹,데몬쓰레드, 쓰레드의 상태] 본문

유튜브 공부/JAVA의 정석 기초편(유튜브)

자바의 정석 기초편 ch13 - 14 ~ 21 [쓰레드의우선순위,쓰레드그룹,데몬쓰레드, 쓰레드의 상태]

소소한나구리 2023. 12. 18. 12:40

1) 쓰레드의 우선순위(priority of thread)

  • 작업의 중요도에 따라 쓰레드의 우선순위를 다르게 설정하여 특정 쓰레드가 더 많은 작업시간을 갖게 할 수 있음
  • 그러나 희망사항에 불가함(마음대로 진행 되지는 않음) - OS의스케줄러가 참고해서 진행 함
void setPriority(int newPriority)	//쓰레드의우선순위를 지정한 값으로 변경
int getPriority()	// 쓰레드의 우선순위를 반환

public static final int MAX_PRIORITY = 10	//최대 우선순위
public static final int MIN_PRIORITY = 1	//최소 우선순위
public static final int NORM_PRIORITY = 5	//보통 우선순위

 

(1) 예제

  • 실행 해보면  특정 쓰레드의 우선순위가 높다하더라도 무조건 먼저 끝나지 않음
  • 쓰레드의 우선순위 값은 상대적으로 계산 됨
class Ex13_6 {
	public static void main(String args[]) {
		runThread1 th1 = new runThread1();
		runThread2 th2 = new runThread2();

		th1.setPriority(5);	
		th2.setPriority(10);

		System.out.println("Priority of th1(-) : " + th1.getPriority());
		System.out.println("Priority of th2(|) : " + th2.getPriority());
		th1.start();
		th2.start();
	}
}

class runThread1 extends Thread {
	public void run() {
		for(int i=0; i < 300; i++) {
			System.out.print("-");
			for(int x=0; x < 10000000; x++);	// 시간지연용 for문
		}
	}
}

class runThread2 extends Thread {
	public void run() {
		for(int i=0; i < 300; i++) {
			System.out.print("|");
			for(int x=0; x < 10000000; x++);
		}
	}
}

2) 쓰레드 그룹

  • 서로 관련된 쓰레드를 그룹으로 묶어서 다루기 위한 것
  • 모든 쓰레드는 반드시 하나의 쓰레드 그룹에 포함 되어 있어야 하며 쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 main쓰레드 그룹에 속함
  • 자신을 생성한 쓰레드(부모쓰레드)의 그룹과 우선순위(기본우선순위 = 5)를 상속받음

Thread클래스의 생성자에 쓰레드 그룹을 지정할 수 있음

ThreadGruop getThreadGroup()	// 쓰레드 자신이 속한 쓰레드 그룹을 반환(속한 그룹 확인)

// 처리되지 않은 예외에 의해 그룹의 쓰레드가 실행이 종료 되었을 때 수행될 동작을 오버라이딩 해줄 수 있음
void uncaughtException(Thread t, Throwable e)

 

(1) 쓰레드그룹의 메서드

ThreadGroup(String name) 지정된 이름의 새로운 쓰레드 그룹을 생성
ThreadGroup(ThreadGroup parent, String name) 지정된 쓰레드 그룹에 포함되는 새로운 쓰레드 그룹을 생성
int activeCount() 쓰레드 그룹에 포함된 활성상태에 있는 쓰레드의 수를 반환
int activeGroupCount() 쓰레드 그룹에 포함된 활성상태에 있는 쓰레드 그룹의 수를 반환
void checkAccess() 현재 실행중인 쓰레드가 쓰레드 그룹을 변경할 권한이 있는지 체크
void destroy() 쓰레드 그룹과 하위 쓰레드 그룹까지 모두 삭제 - 단 비어있어야 삭제 가능
int enumerate(Thread[] list)
int enumerate(Thread[] list, boolean resurse)
int enumerate(ThreadGroup[] list)
int enumerate(ThreadGroup[] list, boolean resurse)
쓰레드 그룹에 속한 쓰레드 또는 하위 쓰레드 그룹의 목록을 지정된 배열에 담고,
그 개수를 반환
두번째 매개변수인 recurse의 값을 true로 하면 쓰레드 그룹에 속한 하위 쓰레드 그룹에 쓰레드 또는 쓰레드 그룹까지 배열에 담음
int getMaxpriority() 쓰레드 그룹의 최대 우선순위를 반환
String getName() 쓰레드 그룹의 이름을 반환
ThreadGroup getParent() 쓰레드 그룹의 상위 쓰레드 그룹을 반환
void interrupt() 쓰레드 그룹에 속한 모든 쓰레드르 interrupt
boolean isDaemon() 쓰레드 그룹이 데몬 쓰레드 그룹인지 확인
boolean isDestroyed() 쓰레드 그룹이 삭제 되었는지 확인
void list() 쓰레드 그룹에 속한 쓰레드와 하위 쓰레드 그룹에 대한 정보를 출력
boolean parentOf(ThreadGroup g) 지정된 쓰레드 그룹의 상위 쓰레드 그룹인지 확인
void setDaemon(boolean daemon) 쓰레드 그룹을 데몬 쓰레드 그룹으로 설정/해제
void setMaxPriority(int pri) 쓰레드 그룹의 최대 우선순위를 설정

3) 데몬 쓰레드

  • 사용자 쓰레드의 작업을 돕는 보조적인 역할을 수행하며 사용자 쓰레드가 모두 종료되면 자동적으로 종료
  • 가비지 컬렉터, 자동저장, 화면 자동갱신 등에 사용

(1) 동작 방식

  • 무한루프와 조건문을 이용해서 실행 후 대기 -> 특정조건이 만족되면 작업을 수행 -> 다시 대기
  • 일반 쓰레드가 종료되면 자동으로 종료됨
  • 해당 쓰레드를 데몬 쓰레드로 변경하는 setDaemon(boolean on)메소드는 반드시 start()를 호출하기 전에 실행 되어야 하며 그렇지 않으면 IllegalThreadStateException이 발생 할 수 있음
boolean isDaemon()          // 쓰레드가 데몬 쓰레드인지 확인, 데몬 쓰레드면 true 반환
void setDaemon(boolean on)  // 쓰레드를 데몬쓰레드로 또는 사용자 쓰레드로 변경
                            // 매개변수 on을 true로 지정하면 데몬 쓰레드가 됨

 

(2) 데몬쓰레드 예제

  • setDaemon(true)로 쓰레드를 데몬쓰레드로 변경
class Ex13_7 implements Runnable  {	// Runnable 인터페이스를 구현(Thread 생성방식 중)
	static boolean autoSave = false;

	public static void main(String[] args) {
		Thread t = new Thread(new Ex13_7());
		t.setDaemon(true);		// 이 부분이 없으면 종료되지 않음
		t.start();

		for(int i=1; i <= 10; i++) {
			try{
				Thread.sleep(1000);	// 1초마다
			} catch(InterruptedException e) {}
			System.out.println(i);

			if(i==5) autoSave = true;	// i값이 5가 되면 autoSave를 true값으로 변경
		}

		System.out.println("프로그램을 종료합니다.");
	}

	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("작업파일이 자동저장되었습니다.");
	}
}

4) 쓰레드의 상태

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

 

(1) 쓰레드의 상태

  • 생성 -> start() -> 실행대기 -> 실행 반복
  • 일시정지 메서드들을 호출하면 일시정지 후 실행 
  • suspend()일시정지 -> resume() 재개
  • sleep()잠자기 -> time-out 시간종료
  • wait() -> notify()
  • join()기다리기, I/O block 입출력 대기 -> interrupt() 깨우기
  • stop() 을 만나면 소멸


(2) 쓰레드의 실행 제어

  • 쓰레드의 실행을 제어할 수 있는 메서드가 제공
  • static이 붙은 메서드는 쓰레드 자기 자신에게만 호출 가능(다른쓰레드에게 적용 불가)
메서드
설명
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()에 의해 일시정지상태인 쓰레드를 실행대기상태로 만듦
Interrupted Exception이 발생하여 일시정지 상태를 벗어남
void stop() 종료 쓰레드를 즉시 종료
void suspend() 일시정지 쓰레드를 일시정지. resume()을 호출하면 다시 실행대기
void resume() 재개 suspend()에 의해 일시정지에 상태에 있는 쓰레드를 실행대기상태로 전환
static void yield() 양보 실행 중 자신에게 주어진 실행시간을 다른 쓰레드에게 양보 -> 자신은 실행대기

 

** 출처 : 남궁성의 정석코딩_자바의정석_기초편 유튜브 강의