2016-04-04 12 views
1

多くの並列呼び出しを実行するテストをAPIに書きたいと思います。executorThreadsPoolの代わりにjavaパラレルストリームを使用する方法は?

devicesList.parallelStream() 
      .map(device -> do something) 

私はjava8並列ストリームでそれを作成している可能性があり:

を私は1つのデバイス上でそれを行うことができますどのように

ExecutorService executor = Executors.newCachedThreadPool(); 
     final int numOfUsers = 10; 
     for (int i = 0; i < numOfUsers; i++) { 
      executor.execute(() -> { 
       final Device device1 = getFirstDevice(); 
       final ResponseDto responseDto = devicesServiceLocal.acquireDevice(device1.uuid, 4738); 
       if (responseDto.status == Status.SUCCESS) 
       { 
        successCount.incrementAndGet(); 
       } 
      }); 
     } 

私はこのように、私はexecutorThreadsPoolを使用してそれを行うことができます知っていますか?

意味同じデバイスを取得するためのコールがほんの少ししか必要ありません。このような

何か:

{{device}}.parallelStream().execute(myAction).times(10) 
+1

すべてのストリームを使用する必要はありません。あなたのコードの代わりに 'コレクション。 nCopies(numOfUsers、() - > {/ *あなたのコード* /})forEach(executor :: execute);または類似の構文... – Holger

答えて

1

はい、それはできますが、...

あなたは

Stream.generate(() -> device) 
     .limit(10) 
     .parallel() 
     .forEach(device -> device.execute()); 

は仕事をするべきだと思います。しかし、なぜ、理由(私は本当に理由がわからない、手がかりがないので)、いいえ。 device.execute()を1秒待ってから何かを印刷させるとします。ストリームは毎秒10回プリントします。だから、それはあなたが望むものではなく、全く平行ではありません。

Googleは私の友人であり、parallelStreamに対して警告する記事が多数見つかりました。

Stream.generate(() -> device) 
     .limit(10) 
     .sorted((a,b)->0) // Sort it (kind of), what?? 
     .parallel() 
     .forEach(device -> device.execute()); 

そして今、それは1秒8の後に出力します。しかし、私の目はhttp://blog.jooq.org/2014/06/13/java-8-friday-10-subtle-mistakes-when-using-the-streams-api/番号8および9 8それはあなたがそれをソートする必要があります、それは魔法のように動作しますコレクションに裏付けされた場合は言っていたに落ちました他の2回目の何回か何回か後に。私は8コアを持っているので、それは私たちの(種類の)ものです。

私のストリームでは.forEach()を使用しましたが、最初は.map()を使用していました。 .map()は印刷されませんでした。ストリームは決して消費されませんでした(リンクされた記事の9を参照)。

ストリームや特にパラレルストリームには注意してください。あなたはストリームが消費されていること、有限であること(.limit())、平行して動作していることなどを確認する必要があります。ストリームは変わっています。

注:device.execute()がブロック操作(IO、networking ...)の場合、同時に実行されるコア数(私の場合は8)を超えることはありません。

更新(Holgerのおかげで):

ホルガーエレガントな代替を与えた:

IntStream.range(0,10) 
     .parallel() 
     .mapToObject(i -> getDevice()) 
     .forEach(device -> device.execute()); 

// Or shorter: 
IntStream.range(0,10) 
     .parallel() 
     .forEach(i -> getDevice().execute()); 

だけforループ(およびそれが動作する)平行に似ています。

+1

'ソート済み 'は興味深いハックです。{0、10} .parallel()。mapToObj(i - > create())を使用する方が良いです。 ).forEach(device - > device.execute()); '... – Holger

関連する問題