[TIL] Java 7일차 1

minami·2021년 2월 23일
0

Java

목록 보기
10/11

💡 10장. 확인문제 4, 5번

✅ throw와 throws의 개념

throws

  • 생성자나 메소드의 선언 끝 부분에 사용되어 내부에서 발생된 예외를 떠넘긴다.
  • throws 뒤에는 떠넘겨야 할 예외를 쉼표(,)로 구분해서 기술한다.
  • 모든 예외를 떠넘기기 위해 간단하게 throws Exception으로 작성할 수 있다.

📌 새로운 예외를 발생시키기 위해 사용된다 👉 throw에 대한 설명!

throw

  • 예외를 최초로 발생시키는 코드이다.
  • throw로 발생된 예외는 일반적으로 생성자나 메소드 선언부에 throws로 떠넘겨진다.
  • throw 키워드 뒤에는 예외 객체 생성 코드가 온다.

📌 예외를 호출한 곳으로 떠넘기기 위해 메소드 선언부에 작성된다. 👉 throws에 대한 설명!

💡 멀티 스레드 (이어서)

6. 스레드 상태 제어

👉 실행 중인 스레드 상태를 변경하는 것

상태 제어 메소드의 종류

  • join(): 스레드A가 실행되는 중에는 대기 상태였다가 스레드A가 끝나면 실행
  • wait(): 일시 정지 상태로 만드는 메소드로 notify() 또는 notifyall()과 쌍으로 사용
  • 사용하지 않는 것을 권장하는 메소드
    • resume(): 일시 정지 상태인 스레드를 강제로 실행 대기 상태로 변경
    • suspend(): 스레드를 일시 정지 상태로 변경
    • stop(): 스레드 즉시 종료

1️⃣ sleep()

👉 주어진 시간 동안 일시 정지

  • 일시 정지할 시간은 밀리 세컨드(1/1000) 단위로 지정
  • interrupt() 메소드를 호출해서 실행 대기 상태로 변경 가능하나 InterruptedException이 발생하므로 예외 처리 필수
public class BeepPrintExample1 {
    
	public static void main(String[] args) {
		Thread thread = new BeepThread();
		thread.start();
		for(int i=0; i<5; i++) {
			System.out.println("띵");
			try { Thread.sleep(500); } catch(InterruptedException e) {}
		}
	}
}

2️⃣ yield()

👉 다른 스레드에게 실행 양보

  • 같거나 더 높은 우선순위를 가진 다른 스레드에게 실행을 양보하고 실행 대기 상태로 간다.

3️⃣ join()

👉 다른 스레드의 종료를 기다림

  • 계산 작업을 하는 스레드가 모든 계산 작업을 마쳤을 때 그 결과값을 받아서 이용하는 경우에 주로 사용하는 메소드

4️⃣ wait(), notify(), notifyAll()

👉 스레드 간 협업

  • 동기화 메소드 또는 동기화 블록에서만 호출 가능한 Object 클래스의 메소드
  • 두 개의 스레드가 교대로 번갈아서 실행되어야 할 경우에 사용

5️⃣ stop 플래그, interrupt()

👉 스레드가 실행 중인데 즉시 종료할 경우, stop() 메소드 대신 안전하게 스레드를 종료하는 방법

stop 플래그

  • stop 필드가 true 또는 false가 될 때를 이용해서 실행 중인 스레드를 종료한다.
public class PrintThread1 extends Thread {
	boolean stop;
	public void setStop(boolean stop) {
		this.stop = stop;
	}
	@Override
	public void run() {
		while(stop==false) {
			System.out.println("실행 중");
		}
		System.out.println("자원 정리");
		System.out.println("실행 종료");
	}
}
public class StopFlagExample {

	public static void main(String[] args) {
		PrintThread1 printThread = new PrintThread1();
		printThread.start();
		try {
			Thread.sleep(1000);
		} catch(InterruptedException e) {}
		printThread.setStop(true);
		//printThread.stop(); // 갑자기 실행중단됨. stop은 사용하지 않길 권고함
	}
}

interrupt() 메소드

  • interrupt() 메소드 사용 시 InterruptedException을 발생시키는 것을 이용하여 실행 중인 스레드를 종료한다.
  • 주의: 스레드가 실행 대기 또는 실행 상태일 때는 InterruptedException이 발생하지 않고, 나중에 일시 정지 상태가 되면 발생한다.
public class PrintThread2 extends Thread {
	@Override
	public void run() {
		// 아래의 try나 while문 중 하나를 사용할 수 있다.
//		try {
//			while(true) {
//				System.out.println("실행 중");
//				Thread.sleep(1);  // 스레드를 일부러 일시 정지시켜 예외 발생 유도
//			}
//		} catch(InterruptedException e) {
//			System.out.println(e.getMessage());  // interrupt는 예외를 발생시켜서 강제로 빠져나가게 하므로 catch에 interrupt 발생 시 할 작업을 넣어준다.
//		} finally {
//			System.out.println("마무리 작업");
//		}
	
		while(true) {
			System.out.println("실행 중");
			if(Thread.interrupted()) {  // 현재 스레드가 interrupted되었는지 확인용
				System.out.println("마무리 작업");
				break;
			}
		}
		System.out.println("마무리 작업");
	}
}
public class InterruptExample {

	public static void main(String[] args) {
		Thread thread = new PrintThread2();
		thread.start();
		try {
			Thread.sleep(1000);
		} catch(InterruptedException e) {}
		thread.interrupt();
	}
}

7. 데몬 스레드 (Daemon Thread)

👉 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드

  • 주 스레드가 종료되면 데몬 스레드도 강제 자동 종료

  • 데몬 스레드 만드는 방법

    주 스레드가 데몬 스레드의 setDaemon(true)를 호출

    • start() 메소드 호출 전에 데몬 스레드를 호출해야 IllegalThreadStateException이 발생하지 않는다!
  • 현재 실행 중인 스레드가 데몬 스레드인지 구별하는 방법

    isDaemon() 메소드 사용

public class AutoSaveThread extends Thread {
	public void save() {
		System.out.println("작업 내용을 저장함.");
	}
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(1000);
			} catch(InterruptedException e) {
				break;
			}
			save();
		}
	}
}
public class DaemonExample {

	public static void main(String[] args) {
		AutoSaveThread autoSaveThread = new AutoSaveThread();
		autoSaveThread.setDaemon(true);
		autoSaveThread.start();
		try {
			Thread.sleep(3000);
		} catch(InterruptedException e) {}
		System.out.println("메인 스레드 종료");
	}
}

8. 스레드 그룹

  • 스레드 그룹은 관련된 스레드를 묶어서 관리 목적으로 이용
  • 계층적으로 하위 스레드 그룹을 가질 수 있다.
  • 스레드는 반드시 하나의 스레드 그룹에 포함되며, 기본적으로 자신을 생성한 스레드와 같은 그룹에 속한다.
  • system 스레드 그룹
    • JVM이 자동으로 생성하는 스레드 그룹
  • system/main 스레드 그룹
    • system 그룹의 하위 스레드 그룹으로 main 스레드가 포함된 그룹
  • 부모 그룹을 지정해주지 않은 경우에는 현재 스레드가 속한 그룹의 하위 그룹으로 생성

스레드 그룹 이름 얻기

  • 현재 스레드가 속한 스레드 그룹의 이름을 얻는 코드

    ThreadGroup group = Thread.currentThread.getThreadGroup();
    String groupName = group.getName();

스레드 그룹 생성

  • 스레드 그룹을 명시적으로 생성하는 코드

    ThreadGroup tg = new ThreadGroup(String name);
    ThreadGroup tg = new ThreadGroup(ThreadGroup parent, String name);
profile
함께 나아가는 개발자💪

0개의 댓글