2017-04-04 1 views
3

Future.cancel (false)은 실제로 작업 실행을 방지 할 수있는 경우에만 true를 반환해야합니다.Future.cancel (false) 실행중인 작업에 대해 true를 반환합니다.

그러나 아래 코드에서 우리는 그것이 모순 된 것을 알 수 있습니다. 작업이이 "Not expecting this statement!!!"

public class Test { 
    public static void main(String[] args) throws InterruptedException { 
     ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 
     final boolean[] canceled = { false }; 
     ScheduledFuture<?> future = executor.schedule(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(1000); 
        if (canceled[0]) 
         System.out.println("Not expecting this statement!!!"); 
       } catch (InterruptedException e) { 
       } 
      } 
     }, 0, TimeUnit.SECONDS); 
     Thread.sleep(100); 
     canceled[0] = future.cancel(false); 

     executor.shutdown(); 
     executor.awaitTermination(2, TimeUnit.SECONDS); 
    } 
} 

을 인쇄하지 말아야 canceld됨에 따라

불행하게도이 프로그램의 출력은 는 "이 문을 기대하지!"입니다

일부 사용자는이 동작을 설명 할 수 있습니까?

답변

5

false으로 canceled[0] = future.cancel(false);을 호출하기 때문에. Future.cancel의 자바 독에서 : 작업이 이미 시작된

경우, mayInterruptIfRunning 매개 변수는이 작업을 실행하는 스레드가 작업을 중지하기위한 시도 중단할지 여부를 결정합니다.

@param mayInterruptIfRunning {true}이 작업을 실행하는 스레드가 인터럽트되어야하는 경우. 당신이 canceled[0] = future.cancel(true);를 호출하는 경우 그렇지 않은 경우, 진행중인 작업,

당신이 cancel 전화

, 당신의 작업이 이미 시작하고 당신이 그것을 완료 할 수 있도록 완료, 그래서 작업이 실제로 성공 취소하고 true를 반환 할 수 있습니다, 당신이 ' 출력을 볼 수 없습니다.

0

코드에서 boolean[] canceled은 두 스레드간에 공유되며이 변수에 대한 동기화 된 액세스가 없습니다. 결과는 예상치 못한 결과입니다. 또한 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)의 설명서에서 작업을 취소 할 수없는 경우 일반적으로 이미 정상적으로 완료되었으므로 false를 반환합니다. 작업을 취소 한 후 로그를 추가하여 어느 것이 먼저 실행되는지 확인하십시오 (항상 도움이되지는 않지만).

+0

내 경우에는 true를 반환합니다. 질문이 제기됩니다. –

+0

주 방법에서 수면 시간을 늘려보십시오. 당신은 다른 대답을 볼 수 있습니다 – prasanth

+0

이 질문에 +1을 준 사람은 처음 15 초 만에 +1을 받았습니다 ... –

관련 문제