2017-09-29 4 views
1

将来のために一つに満たされたときに実行されている他の今後の課題を終了します。私は現在同期しています。私はそれを並行してやりたいと思って、それをjavaのFutureを使って行うことができることを知りました。私はURLからファイルをダウンロードするためにapache.commons.ioを使用しています。ここ は、コードスニペットです:指定した検索が一つだけのサーバの中に見出されることが期待されているよう条件は、Java 8</p> <p>私はdiffのサーバからファイルをログインして、これらのログファイル内の指定されたテキストを検索ダウンロードするPROGを書くしようとしているを使用してタスク

ExecutorService executorService = Executors.newCachedThreadPool(); 
    List<Future<XCluster>> clusterFutures = new ArrayList<>(); 
    for(XCluster cluster: clusters) { 
     clusterFutures.add(executorService.submit(() -> { 
      return downloadAndSearch(textToSearch, cluster); 
     })); 
    } 
    //For now I'm not doing anything with returned value from Future 

しかし、今、私は他のダウンロード・検索操作を終了したい未来の下で始まりました。だから私が始めた他の未来の仕事を続ける必要はない。どのようにこれを行う方法を示唆することができますか?私はJava 8を使用しています、他のオプションも歓迎です。前もって感謝します!

答えて

1

ExecutorServiceには、すべてのスレッドを停止してサービスをシャットダウンするshutdownNowメソッドがあります。

編集:

私はshutdownNowので、私は私が思ったとして、それがスレッドを停止することはできません見るようにいくつかの実験を行いました。 AFAIK割り込み()を使用しますが、すべてのスレッドが割り込みに反応するわけではありません。

だから私が思い付くことができる最高の選択肢:

まず、インジケータクラスを作成します。あなたが開始

public static class Indicator{ 

    private boolean isReady = false; 

    public void ready(){ 
     isReady = true; 
    } 

    public boolean isReady(){ 
     return isReady; 
    } 
} 

スレッドが通信する一つの指標インスタンスを共有する必要があります。 ですから、このような呼び出し可能な作成することができます:最初のスレッドは、それが他の人を停止することができ、彼らはhimselves後にクリーンアップする準備ができている

public static class Processor implements Callable<Integer> { 

    private volatile Indicator indicator; 

    private Integer number; 

    public Processor(Integer integer, Indicator isReady){ 
     this.number = integer; 
     this.indicator = isReady; 
    } 

    @Override 
    public Integer call() throws Exception { 
     System.out.println("Thread started:" + Thread.currentThread().getId()); 
     int counter = 0; 
     while (!indicator.isReady &&counter < number) { 
      // Make complicated things 
      Math.sin(counter); 
      counter++; 
     } 
     if(indicator.isReady){ 
      //another thread finished 
      //delete resources 
      System.out.println("Thread interrupted: " + Thread.currentThread().getId() + " " + counter); 
      return -1; 
     } else { 
      System.out.println("Thread finished: " + Thread.currentThread().getId() + " " + counter); 
      indicator.ready(); 
      return counter; 
     } 
    } 
} 

この道を。

次のように私はこれを試してみました:

public static void main(String[] args) throws ExecutionException, InterruptedException { 
    ExecutorService executorService = Executors.newCachedThreadPool(); 
    List<Future<Integer>> clusterFutures = new ArrayList<>(); 
    Indicator indicator = new Indicator(); 
    clusterFutures.add(executorService.submit(new Processor(100, indicator))); 
    clusterFutures.add(executorService.submit(new Processor(10000, indicator))); 
    clusterFutures.add(executorService.submit(new Processor(10000000,indicator))); 
} 

にサンプル出力:

Thread started:11 
Thread started:12 
Thread finished: 11 100 
Thread interrupted: 12 1001 
Thread started:13 
Thread interrupted: 13 0 

追記:参照されるクラスは、ちょうど実験中に作るために簡単だった静的な内部クラスである必要はありませんが1つのファイル。コードの面では

+0

ありがとう、もう一度ポイント。最終的には他のスレッドをシャットダウンするときに実行されるようなコードブロックを持つ方法がありますか?私は他の先物によってダウンロードされたファイルをきれいにする必要があります。 – user3539951

0

、最も簡単な解決策は、すべての先物をキャンセルシャットダウンスレッドを持つことです。

final ExecutorService executorService = Executors.newCachedThreadPool(); 
    final ExecutorService shutdownService = Executors.newSingleThreadExecutor(); 
    List<Future<XCluster>> clusterFutures = new ArrayList<>(); 
    for(XCluster cluster: clusters) { 
     clusterFutures.add(executorService.submit(() -> { 
      boolean cancelOthers = false; 
      try { 
       XCluster result = downloadAndSearch(textToSearch, cluster); 
       cancelOthers = yourPredicateOfSuccess(); 
       return result; 
      } finally { 
       if (cancelOthers) { 
       shutdownService.execute(() -> { 
        executorService.shutdownNow(); 
       }); 
       } 
      } 
     })); 
    } 

これはあなたがいないということなるため、他のスレッドとのtry-最終的には重要ですほとんど成功したメソッドの実行をキャンセルします。

+0

ありがとう、私はこのアプローチを私は他の未来をシャットダウンしたが、その動作していない試みた。 shutdownNow()を呼び出した後でも、スレッドは実行を継続します。 – user3539951

関連する問題

 関連する問題