2017-12-01 4 views
0

私は、CompletableFutureの実行時間をチェックするメソッドを持っています。そのようなCompletableFutureが2秒以上実行されている場合、私はこのタスクを終了したい。しかし、私は、CompletableFutureメソッドが実行されている制御スレッドを持っていないとどうすればいいですか? responseFutureは、メソッドをやっているところCompletableFuture関連スレッドを削除するにはどうすればいいですか?

 final CompletableFuture<List<List<Student>>> responseFuture = new CompletableFuture<>(); 
responseFuture.supplyAsync(this::createAllRandomGroups) 
     .thenAccept(this::printGroups) 
     .exceptionally(throwable -> { 
      throwable.printStackTrace(); 
      return null; 
     }); 

createAllRandomGroups()

private List<List<Student>> createAllRandomGroups() { 
    System.out.println("XD"); 
    List<Student> allStudents = ClassGroupUtils.getActiveUsers(); 
    Controller controller = Controller.getInstance(); 
    List<List<Student>> groups = new ArrayList<>(); 
    int groupSize = Integer.valueOf(controller.getGroupSizeComboBox().getSelectionModel().getSelectedItem()); 
    int numberOfGroupsToGenerate = allStudents.size()/groupSize; 
    int studentWithoutGroup = allStudents.size() % groupSize; 
    if (studentWithoutGroup != 0) groups.add(this.getListOfStudentsWithoutGroup(allStudents, groupSize)); 
    for(int i = 0; i < numberOfGroupsToGenerate; i++) { 
     boolean isGroupCreated = false; 
     while (!isGroupCreated){ 
      Collections.shuffle(allStudents); 
      List<Student> newGroup = this.createNewRandomGroupOfStudents(allStudents, groupSize); 
      groups.add(newGroup); 
      if (!DataManager.isNewGroupDuplicated(newGroup.toString())) { 
       isGroupCreated = true; 
       allStudents.removeAll(newGroup); 
      } 
     } 
    } 
    DataManager.saveGroupsToCache(groups); 
    return groups; 
} 

printGroups()

private void printGroups(List<List<Student>> lists) { 
     System.out.println(lists); 

    } 

この文responseFuture.cancel(true);は、スレッドを殺すことはありません。では、CompletableFutureスレッドを終了させる最もエレガントな方法は何ですか?

+0

あなたは、殺すためのスレッドがあると仮定しています。しかし、これは非同期操作の連鎖のように見えますが、スレッドがまったく待機していない可能性があります。スレッドを強制終了したくない場合は、非同期操作をキャンセルする必要があります。 –

+0

@ DanielPrydenだから、どうすればこれらの操作を殺すことができますか? – masterofdisaster

+0

どの操作が時間を費やしているかによって異なります。'createAllRandomGroups'と' printGroups'のコードを表示できますか? –

答えて

0

スレッドを終了する唯一の方法は、割り込みによるものです。これは協調的なメカニズムです。これは、スレッドがInterruptedExceptionを処理することによって割り込みロジックを実装する必要があることを意味します。

しかし、あなたが所有していないスレッドを中断するのは本当に悪い習慣です。あなたのケースだと思います。

+0

どうすればこれらの非同期操作を強制終了できますか? – masterofdisaster

4

段のチェーンをのように作成すると、この便利な方法でさまざまなコンポーネントの設定が作成されます。基本的には、これらのコンポーネントはa → function → bと呼ばれ、aの完了によりfunctionの評価がトリガーされ、bがまだ完了していないかどうかが事前に確認され、機能が評価され、bが完了します。

しかし、b自体は、functionまたはそれを評価するスレッドについての知識がありません。実際にはfunctionbには特別ではありません。complete,completeExceptionallyまたはcancelを最初の1つのスレッドから呼び出すことができます。したがって、は完了可能のクラス名になります。

関数を評価するスレッドを手に入れる唯一の方法は、最初から関数を制御することです。今

ExecutorService myWorkers = Executors.newFixedThreadPool(2); 

CompletableFuture<FinalResultType> future 
    = CompletableFuture.supplyAsync(() -> generateInitialValue(), myWorkers) 
         .thenApplyAsync(v -> nextCalculation(v), myWorkers) 
         .thenApplyAsync(v -> lastCalculation(v), myWorkers); 
future.whenComplete((x,y) -> myWorkers.shutdownNow()); 

futureの完了、例えばキャンセルによって、このチェーンによって新たな評価が行われないようにし、継続的な評価があればそれを中断させようと試みます。

タイムアウトを実装することができます。スレッドプールのシャットダウンによるタスクの拒絶が完全に決してに中間将来のいくつかを引き起こす可能性がありますが、ステージのこのチェーンのために、これは無関係であること

try { 
    try { 
     FinalResultType result = future.get(2, TimeUnit.SECONDS); 
     System.out.println("got "+result); 
    } 
    catch(TimeoutException ex) { 
     if(future.cancel(true)) System.out.println("cancelled"); 
     else System.out.println("got "+future.get()); 
    } 
} 
catch(ExecutionException|InterruptedException ex) { 
    ex.printStackTrace(); 
} 

ありません。重要なのは、最後の段階futureが完了したことです。シャットダウンをトリガーする完了であるため、保証されています。

+0

しかし、タイムアウト後に呼び出されるcancelメソッドは、この未来を本当に殺すか、それを殺そうとしていますか? – masterofdisaster

+0

'CompletableFuture'の場合、取り消しは単に完了の特殊な形式なので、取り消しに成功するか、将来の他の手段で完了したという2つの可能な結果のうちの1つしか持てません。どちらの場合でも、「キャンセル」が戻ったとき、未来は完了します。私の答えの解決策は、どのような完了が起こったかにかかわらず、エグゼキュータをシャットダウンします。そして、新しいタスクをスケジューリングできないことが保証されます。すでに実行中の評価は中断され、早期に終了するにはその側で中断サポートが必要です。その周りに道はありません。 – Holger

関連する問題