2017-11-29 2 views
1

참고 : 이것은 장난감 코드이며 제작 준비가되지 않았습니다.작업에서 with with ScheduledExecutorService의 Runnable 작업 중지

모든 고정 지연 (예 : 2 초)을 실행하려면 MyTask을 예약하고 싶습니다. 그리고이 일이 끝나면 스스로 멈추기를 원합니다. MyTask에 대한 코드는 다음과 같습니다

public class MyTask implements Runnable { 
    MainClass parent; 
    AtomicInteger integer = new AtomicInteger(0); 
    public MyTask(MainClass parent) { 
     this.parent = parent; 
    } 

    @Override 
    public void run() { 
     try { 
      int valueNow = integer.incrementAndGet(); 
      System.out.println("Running with value: " + valueNow + " and going to do work"); 
      Thread.sleep((long)(Math.random() * 10000)); // simulate some work 
      System.out.println("Running with value: " + valueNow + " and work over"); 
      if(valueNow == 5) { 
       parent.stopTask(); 
      } 
     } catch (Exception exception) { 
      System.out.println("Interrupted"); 
     } 
    } 
} 

그리고 MainClass은 일정 그것을 하나입니다

public class MainClass { 
    private ScheduledExecutorService executorService; 
    private ScheduledFuture updateFuture; 
    public static void main(String[] args) { 
     new MainClass().startMyTask(); 
    } 
    public void startMyTask() { 
     System.out.println("Starting MyTask to run every 2 seconds.............."); 
     executorService = Executors.newScheduledThreadPool(2); 
     updateFuture = executorService.scheduleAtFixedRate(new MyTask(this), 1, 2, TimeUnit.SECONDS); 
    } 
    public void stopTask() { 
     System.out.println("Stopping MyTask to run further"); 
     updateFuture.cancel(true); 
    } 
} 

이 시나리오를 재현 단지 장난감 코드입니다. 이 접근법에 문제가 있습니까? 어디서 멈출 수 있도록 부모에 대한 참조를 스레드에 전달합니까? 더 좋은 방법이 있습니까?

+0

괜찮습니다. 무엇이 문제입니다? – canillas

+0

@canillas 내 질문에 대한 접근 방식입니다. 작업 자체가 중단되기를 원한다면 더 나은 접근 방법이 있습니까? –

답변

0

글쎄, '틀린'것은 두 클래스 사이에 주기적 종속성을 만드는 것입니다. 작동하지만 순환 종속성은 일반적으로 바람직하지 않습니다.

그러나주기를 깨뜨리는 것은 쉽습니다. 부모 자체를 전달하는 대신 작업을 완료하면 Runnable을 수락 할 수 있습니다. 기본적으로 콜백.

public class MyTask implements Runnable { 
    Runnable runOnDone; 
    AtomicInteger integer = new AtomicInteger(0); 
    public MyTask(Runnable runOnDone) { 
     this.runOnDone = runOnDone; 
    } 

    @Override 
    public void run() { 
     try { 
      int valueNow = integer.incrementAndGet(); 
      System.out.println("Running with value: " + valueNow + " and going to do work"); 
      Thread.sleep((long)(Math.random() * 10000)); // simulate some work 
      System.out.println("Running with value: " + valueNow + " and work over"); 
      if(valueNow == 5) { 
       runOnDone.run(); 
      } 
     } catch (Exception exception) { 
      System.out.println("Interrupted"); 
     } 
    } 
} 

작업은 다음과 같이 인스턴스화 할 수 있습니다 new MyTask(this::stopTask)

은 또한 당신은 또한이 재조정되고 종료되는, 귀하의 작업에서 예외를 던질 수 있습니다. this stackoverflow answer을 참조하십시오.

+0

'valueNow == 5 '조건은 다음 사이클에서 태스크가 더 이상 실행되지 않게하는 것입니다. 왜 하나 더 실행 파일을 불러내시겠습니까? 나는 현재 실행을 멈추고 싶다. –

+0

새 스레드를 생성하지 않습니다. 같은 스레드에서 실행 파일을 실행하고 있습니다. – bowmore

+0

'Runnable'은 실행될 때 약간의 코드를 실행하는 추상화에 지나지 않습니다. – bowmore