join 필요 배경
만약에 프로그램이 실행되는 과정에서
어떤 계산에 대한 결과값을 받아서 다음 로직을 실행해야 되는 상황이라면..
어떻게 처리해야할까?
스레드A가 스레드B의 결과값을 참조하려할때
단순히 루프를 돌려서 스레드B의 종료를 확인할 수 있다.
그러나 이 방법은 스레드A의 실행을 방해하여 느리게 하므로 비효율적이다.
예제
1. 팩토리얼 계산 스레드 실행
팩토리얼 계산을 여러개 한번에 실행하는 경우
각각의 계산은 각각의 스레드로 실행
모든 스레드의 실행이 끝났을때 값을 출력하기를 원함
public static class FactorialTread extends Tread {
private long inputNumber;
private BigInteger result = BigInteger.ZERO;
private boolean isFinished = false;
public FactorialTread(long inputNumber) {
this.inputNumber = inputNumber;
}
public void run(){
this.result = factorial(inputNumber);
this.isFinished = true;
}
public BigInteger factorial (long n) {
BigInteger tempResult = BigInteger.ONE;
for(long i=n; i>0;i--){
tempResult = tempResult.multiply(new BigInteger(Long.toString(i)));
}
return tempResult;
}
public boolean isFinished(){
return isFinished;
}
public BigInteger getResult(){
return result;
}
}
public static void main(String[] args){
List<Long> inputNumbers = Array.asList(0L, 3435L, 654353L, 47564L, 55L);
List<FactorialThread> threads = new ArrayList<>();
for(long inputNumber : inputNumbers){
threads.add(new FactorialThread(inputNumber));
}
for(FactorialThread thread : threads){
thread.start();
}
for(int i=0; i<threads.size(); i++){
FactorialThread factorialThread = threads.get(i);
if(factorialThread.isFinished()){
System.out.println("Factorial of "+inputNumbers.get(i)+"is"+factorialThread.getResult);
}else{
System.out.println("The caculation for "+inputNumbers.get(i)+"is still innprogress");
}
}
}
위의 코드를 실행했을때
팩토리얼스레드와 메인스레드 사이에서 경쟁이 발생하며,
시간이 짧게걸리는 스레드는 종료되어서 결과값을 보여주지만
대부분은 진행중으로 로그가 찍힌다.
2. 모든 계산의 결과를 출력
아래와 같이 각각의 스레드에 join()메서드를 실행해서
모든 팩토리얼스레드가 작업을 마칠때까지 메인스레드가 기다리게한다.
for(FactorialThread thread : threads){
thread.start();
thread.join(); //추가
}
3. 스레드에 제한시간 설정
너무 오래걸리는 계산의 경우, 메인스레드가 계속 기다려야한다.
그럴때 스레드에 제한시간을 설정해보자.
join 메서드의 파라미터로 시간을 설정한다.
thread.join(2000);
위의 코드는 2초동안 스레드가 종료되지않으면
스레드를 반환한다.
그러나 인터럽트하지 않아서 스레드는 종료되지않고 여전히 실행중이다.
(메인스레드는 종료)
4. 팩토리얼 스레드 인터럽트
가장 간단한 방법은
팩토리얼 스레드를 데몬스레드로 만들어서 메인스레드가 종료될때 인터럽트 되도록 하는 방법이다.
thread.setDemon(true);
thread.start();
'Back > Java' 카테고리의 다른 글
[Java] 서버 실행 환경 조회하기 (베타인지 확인해서 로직 적용) (0) | 2023.11.05 |
---|---|
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드종료 및 데몬스레드 퀴즈 (0) | 2023.03.31 |
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드조정 (스레드 종료 및 Demon 스레드) (0) | 2023.03.27 |
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드생성2부. 스레드 상속 (도둑과 경찰 예제) (0) | 2023.03.26 |
[JAVA/멀티스레드] JAVA멀티스레딩 - 스레드생성1부. 스레드의 기능과 디버깅 (0) | 2023.03.24 |