2011-06-21 7 views
1

私はいくつかのタスクをマルチスレッドで行う必要があります。
私はすべてのタスクが完了したら私のプログラムを続けることを前もって知っています。
この目的には次のコードが適していますか?コールウェイと先物マルチスレッドを適切な方法で使用していますか(java)?

public void test() { 
    Callable<String> myCall = new Callable() { 

     @Override 
     public String call() throws Exception { 
      return doDomething(); 
     } 
    }; 


    Callable<String> myCall2 = new Callable() { 

     @Override 
     public String call() throws Exception { 
      return doDomething2(); 
     } 
    }; 

    ExecutorService executor = Executors.newFixedThreadPool(2); 
    List<Callable<String>> list = Arrays.asList(myCall,myCall2); 
    List<Future<String>> futuresList = executor.invokeAll(list); 

    String result1 = futuresList.get(0).get(); 

    String result2 = futuresList.get(0).get(); 

    //... 
} 

私はジェネリックで動作するようにこれを変更しようとしています:

public void test() { 
Callable<?> myCall = new Callable() { 

    @Override 
    public String call() throws Exception { 
     return doDomething(); 
    } 
}; 


Callable<?> myCall2 = new Callable() { 

    @Override 
    public String call() throws Exception { 
     return doDomething2(); 
    } 
}; 

ExecutorService executor = Executors.newFixedThreadPool(2); 
List<Callable<?>> list = Arrays.asList(myCall,myCall2); 
List<Future<?>> futuresList = executor.invokeAll((Collection<? extends Callable<?>>)list); 

String result1 = futuresList.get(0).get(); 

String result2 = futuresList.get(0).get(); 

// ... 
} 

は、私は次のコンパイルエラーが表示されます。

The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Collection<capture#2-of ? extends Callable<?>>) .

+0

大丈夫ですが、そのコードの実行に問題はありますか? –

+0

いいえ、同じことをする別の実装があるのだろうかと思っていました。たとえば、実行者サービスを使用せずにこれを実装できますか? – AAaa

+0

なぜあなたは 'ExecutorService'を使わずにそれをしたいのですか?生の 'Thread'sであなたが望むものを達成することができますが、executorフレームワークが存在するので、複雑さに対処する必要はありません。 – ColinD

答えて

2

別にあなたがゼロ番目のインデックスにアクセスしてから、二度と私は何も間違っているとは見ません。

この編集は、ExecutorServiceを使用せずに実装する方法に関するご質問と関連しています。 ColinDノートとして、あなたは本当にないは、私が今、何をしたい場合は、2つのオブジェクトを必要とし、ラッチ

String result1 = null; 

String result2 = null; 

public void test() { 
    Thread thread1 = new Thread(new Runnable(){ 
     public void run(){ 
      result1 = doSomething(); 
     } 
    }); 
    Thread thread2 = new Thread(new Runnable(){ 
     public void run(){ 
      result2 = doSomething2(); 
     } 
    }); 
    thread1.start(); 
    thread2.start(); 
    thread1.join(); 
    thread2.join(); 
    ... 
    ... 

} 

ように2つのスレッドを使用した機能の同じセットを取得するには、なぜ

が表示されます必要があります別のスレッド/作業単位を追加するには、

Thread thread3 = new Thread(new Runnable(){ 
      public void run(){ 
       result3 = doSomething3(); 
      } 
     }); 
thread3.start(); 
thread3.join(); 

などが必要です。したがって、あなたのソリューションはこれを行うためのより良い方法です。

+0

詳細なお返事ありがとうございます。私が上記のコメントに書いたことがなぜコンパイルされないのか知っていますか? – AAaa

1

さて、私は悪魔の主張者にしましょう。 この例の中で唯一実際にあなたに当たっているのは、おそらく他のプログラマーには分かりにくい2つのメソッドを呼び出しているという事実です。

これは単なる例ですが、他のプログラマはdoSomethingdoSomething2が同期して実行されるため、「共有可能な状態」を持たないことを認識しないかもしれません。この設定ではそれほど明白ではありません。

実際にロジックを別のクラスに入れることをお勧めします。

+0

あなたはどうか説明できますか? – AAaa

関連する問題