이 자바 클래스에 대해 배우기 위해 더미 프로그램을 만들고 있습니다. 내 시간 제한 작업은 중단하기 전에 3 초의 시간을주지 않는 작업을 호출합니다. 코드는 다음과 같습니다.
FutureTask<Integer> task = new FutureTask<>(new
Callable<Integer>(){
@Override
public Integer call() throws Exception {
int i =0;
while(i<100000){
;
}
return 0;
}
});
executor.execute(task);
try {
task.get(3000, TimeUnit.MILLISECONDS);
System.out.println("Everything was ok");
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException ex){
boolean result = task.cancel(true); //here i cancel the thread
System.out.println("the task has timed out "+result);
}
무슨 일이 일어나면 catch 블록이 실행되지만 스레드가 끝날 때까지 내 프로그램이 계속 실행됩니다. task.cancel이 수락되지 않은 것과 같습니다. 왜 그런 겁니까?
작업은 컴퓨팅 바운드입니다. IO 또는 절전을 수행하지 않으며 JVM이 인터럽트 플래그 (를 throw하는 모든 메서드 InterruptedException
)를 확인할 때입니다. 따라서 작업은 중단되지 않습니다.
인터럽트 튜토리얼을 읽어 볼 가치가 있습니다. 노트 :
InterruptedException을 발생시키는 메서드를 호출하지 않고 스레드가 오래 지속되면 어떻게 될까요? 그런 다음 주기적으로 Thread.interrupted를 호출해야하며, 인터럽트가 수신되면 true를 반환합니다. 예를 들면 :
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
그리고 또한
인터럽트 메커니즘은 인터럽트 상태로 알려진 내부 플래그를 사용하여 구현됩니다. Thread.interrupt를 호출하면이 플래그가 설정됩니다. 스레드가 정적 메서드 Thread.interrupted를 호출하여 인터럽트를 확인하면 인터럽트 상태가 지워집니다. 한 스레드가 다른 스레드의 인터럽트 상태를 쿼리하는 데 사용하는 비 정적 isInterrupted 메서드는 인터럽트 상태 플래그를 변경하지 않습니다.
꽤 자주 사람들은 다음과 같은 내용을 작성합니다.
try {
// interruptible operation
}
catch (InterruptedException e) {
// do nothing
}
중단 된 플래그를 재설정하지 않습니다. 따라서 무중단 코드가 생성됩니다. 자세한 내용은 이 JavaSpecialists 뉴스 레터 를 참조하십시오.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다