2017-02-26 1 views
0

안녕하세요 저는 동시성에 초보자이므로 future.isDone() 메서드가 true를 표시하는지 여부를 스레드 완료시 확인하는 매우 기본적인 프로그램을 작성했습니다. , 불행히도 scheduledAtFixedRate 메서드를 사용하여 작업을 예약 할 때 항상 "false"를 표시합니다. 그러나 일정 방법을 사용하면 "true"로 표시되지만 간단한 작업은 초 후에 다시 실행되지 않습니다. 왜 이런 경우인지 이해하는 데 도움이되는 제안이나 설명은 많은 도움이 될 것입니다.Executor.scheduleAtFixedRate 메서드를 사용할 때 Future.isDone()이 상태 변경을 표시하지 않음

감사합니다. 코드와 여기에

:

package com.company; 

import org.testng.annotations.Test; 

import java.util.ArrayList; 
import java.util.List; 

import java.util.concurrent.*; 


public class Main { 

public static void main(String[] args) { 

    Main mn = new Main(); 
    System.out.println("Main thread started..."); 
    mn.runobjects(); 
    System.out.println("Main thread stopping..."); 
} 



@Test 
public void runobjects(){ 
    List<commonrun> Obj = new ArrayList<>(); 
    Obj.add(new TestObj1()); 
    Obj.add(new TestObj2()); 
    Obj.add(new TestObj3()); 
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); 
    ScheduledFuture<?> futures1 = null; 
    ScheduledFuture<?> futures2 = null; 
    ScheduledFuture<?> futures3 = null; 
    int i=0; 
    for (commonrun obj : Obj){ 
     if (i==0) { 
      futures1 = executor.schedule(() -> obj.runme(), 0, TimeUnit.SECONDS); 
     } 
     if (i==1) { 
      futures2 = executor.scheduleAtFixedRate(() -> obj.runme(), 0, 10, TimeUnit.SECONDS); 
     } 
     if (i==2) { 
      futures3 = executor.scheduleAtFixedRate(() -> obj.runme(), 0, 10, TimeUnit.SECONDS); 
     } 
     i++; 
    } 

    while(true){ 

     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Thread 1 is done : "+ futures1.isDone()); 
     System.out.println("Thread 2 is done : "+ futures2.isDone()); 
     System.out.println("Thread 3 is done : "+ futures3.isDone()); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 



} 
} 

package com.company; 

public interface commonrun { 

    public void runme(); 
} 

package com.company; 

public class TestObj1 implements commonrun { 

    static int counter = 0; 
    @Override 
    public void runme() { 
     System.out.println("Object 1 Starting... run : " + counter); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Object 1 Stopping... run : " + counter); 
     counter++; 

    } 
} 

package com.company; 

public class TestObj2 implements commonrun { 
    @Override 
    public void runme() { 
     System.out.println("Object 2 Starting..."); 
     try { 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Object 2 Stopping..."); 

    } 
} 

package com.company; 

public class TestObj3 implements commonrun { 
    @Override 
    public void runme() { 
     System.out.println("Object 3 Starting..."); 
     try { 
      Thread.sleep(3000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Object 3 Stopping..."); 

    } 
} 
+1

"executor.scheduleAtFixedRate()"를 사용하면 Future-Objects가 반환되지 않기 때문입니다. 이 결정은 작업이 실행될 때마다 메서드가 새로운 Future-Object를 반환하기 때문에 이루어졌습니다. 그리고 아무도이 작업이 얼마나 자주 실행되는지 알지 못하기 때문에 Java 설계자는이 홍수를 사전에 방지하기로 결정했습니다. – DiabolicWords

답변

0

ScheduledExecutorService.scheduleAtFixedRate() 일정 반복적 인 작업. 절대로 (자연적으로) 끝내지 않으므로 끝나지 않을 것입니다. 방법의 설명서에서 :

이 작업은 취소 또는 집행 따라서

의 종료로 종료됩니다, 당신은 future.cancel() 또는 executor.terminate()를 호출하는 경우에만 작업은 수행 다음 future.isDone() 것이다 반환 될 것입니다 true.

한 잠재적 future빨리 첫 번째 작업의 실행이 완료로를 수행 될 것을 기대할 수 있지만,이 이유는 다음의 경우에는 해당되지 않습니다 :

  1. 미래는 그것을 "취소"(수 없습니다 할 수있게되면 "done"은 미래의 터미널 상태 임), 따라서 isDone은 반복적 인 작업의 현재 실행 상태를보고 할 수 없습니다.
  2. 미래가 완료되면 취소 할 수 없습니다 (취소 할 항목이 없습니다). 취소 될 때까지 무한정 실행되지 않는 반복적 인 작업에는 적합하지 않습니다.
+0

사실입니다. 그러나 주된 이유는 몇 초 전에 언급했듯이 각 완료된 작업이 새로운 Future-Object를 반환한다는 것입니다. 이것은 미래 객체의 끝없는 시리즈를 생성합니다. 따라서 일정에 따라 일정을 잡을 때 매개 변수로 Runnables 및 Callable 만 가져올 수 있습니다. Callnables가 실행하는 Runnables는 Future-Object를 돌려주지 않기 때문에. – DiabolicWords

+0

'Future'에 의해 반환 될 _value_가 없지만'Future'는 여전히 수행 될 수 있습니다. 귀하의 의견은 친절하게 설명을 보완합니다. –

+0

답변을 얻은 모든 이들에게 ... 정말 감사드립니다. –

관련 문제