스레드 조정
하나의 스레드를 다른 스레드에서 멈추게하는 작업
스레드를 멈추게 하는 이유 (스레드 조정 이유)와 스레드 조정방법 (멈추는 방법)
1. 사용하지 않는 스레드의 리소스 정리
- 스레드는 아무것도 하지 않을때도 리소스를 사용한다.
- 메모리와 일부 커널 리소스를 사용하고, 스레드가 실행중이라면 CPU시간 뿐만 아니라 CPU 캐시공간도 사용한다.
- 그러므로 생성한 스레드가 이미 작업을 완료했는데, 애플리케이션은 작동 중이라면 사용하지 않는 스레드가 사용하는 리소스는 정리해야 한다.
예제
스레드 sleep메서드에서는 interruptedException이 발생하면 직접 처리해야 하는게 명확하다
package thread.interrupt;
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new BlockingTasks());
thread.start();
// 이 스레드가 인터럽트 될때, 예외처리 발생
thread.interrupt();
}
private static class BlockingTasks implements Runnable {
@Override
public void run() {
try {
Thread.sleep(50000);
} catch (InterruptedException e) {
//아래 내용 출력 후 스레드 바로 종료
System.out.println("Existing blocking thread");
}
}
}
}
2. 스레드가 오작동할때
- 응답이 없는 서버에 계속 요청을 보내는 경우
- 우리가 허용하는 것보다 오래 긴 계산을 전송하고 있을 경우 등
- 어떤식으로든 스레드가 오작동한다면 중지해야한다.
예제
package thread.interrupt;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new LongComputationTasks(new BigInteger("2"), new BigInteger("10")));
thread.start();
}
private static class LongComputationTasks implements Runnable {
private BigInteger base;
private BigInteger power;
public LongComputationTasks(BigInteger base, BigInteger power) {
this.base = base;
this.power = power;
}
@Override
public void run() {
System.out.println(base + "^" + power + "=" + pow(base, power));
}
private BigInteger pow(BigInteger base, BigInteger power) {
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ZERO; i.compareTo(power) != 0; i.add(BigInteger.ONE)) {
result = result.multiply(base);
}
return result;
}
}
}
- base와 power의 값이 많이 커지게 되면, 예를 들어 20000^1000000000
- 계산이 끝날때까지 기다리거나 스레드를 인터럽트해서 앱을 종료해야한다.
- 인터럽트를 해도, 이를 처리할 메서드나 로직이 없기 때문에 LongComputation은 계속 돌아간다
- 이런 경우, 코드 내에서 시간이 오래 걸리는 핫스팟을 찾아서 외부에서 인터럽트를 당했는지는지를 확인한다.
private BigInteger pow(BigInteger base, BigInteger power) {
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ZERO; i.compareTo(power) != 0; i.add(BigInteger.ONE)) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Prematurely interrupted computation");
return BigInteger.ZERO;
}
result = result.multiply(base);
}
return result;
}
3. 애플리케이션 전체를 중단하기 위해
- 메인스레드가 종료됐어도 최소 하나의 스레드가 실행되고 있다면 애플리케이션은 종료되지 않는다
- 그래서 애플리케이션을 끝내기전에 모든스레드를 중단할 기능이 필요
- 이럴때 데몬스레드가 필요하다.
Demon threads
- 배경에서 실행되는 스레드
- 앱의 주작업이 아닌 백그라운드 작업을 담당
- 텍스트에디터 프로그램의 경우, 몇분마다 작업을 파일에 저장하는 스레드
- 데몬스레드는 애플리케이션의 종료에 영향을 줄수 없다.
- 데몬스레드가 끝나지않아도 메인 스레드가 끝나면 애플리케이션이 종료된다.
예제
- Daemon 속성을 'true'로 설정해서 스레드를 데몬스레드로 지정할 수 있다.
- thrad.setDaemon(true);
- 메인 스레드가 종료됐다는 것만으로 전체 앱이 종료되는걸 볼 수 있다
'Back > Java' 카테고리의 다른 글
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드연결 (join) (0) | 2023.04.05 |
---|---|
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드종료 및 데몬스레드 퀴즈 (0) | 2023.03.31 |
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드생성2부. 스레드 상속 (도둑과 경찰 예제) (0) | 2023.03.26 |
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드생성1부. 스레드의 기능과 디버깅 (0) | 2023.03.24 |
[JAVA/멀티스레드] JAVA멀티스레딩 - 운영체제기초2 (컨텍스트 스위치) (0) | 2023.03.22 |