2017-08-29 14 views
-1

java-driver-async-queriesを使用して非同期クエリを実装しようとしました。 FutureCallback内のリストを変更していますが、機能していないようです -ResultSetFutureでコレクションを変更する

List<Product> products = new ArrayList<Product>(); 

for (// iterating over a Map) { 
    key = entry.getKey(); 
    String query = "SELECT id,desc,category FROM products where id=?"; 
    ResultSetFuture future = session.executeAsync(query, key); 
    Futures.addCallback(future, 
     new FutureCallback<ResultSet>() { 
      @Override public void onSuccess(ResultSet result) { 
       Row row = result.one(); 
       if (row != null) { 
        Product product = new Product(); 
        product.setId(row.getString("id")); 
        product.setDesc(row.getString("desc")); 
        product.setCategory(row.getString("category")); 

        products.add(product); 
       } 
      } 

      @Override public void onFailure(Throwable t) { 
       // log error 
      } 
     }, 
     MoreExecutors.sameThreadExecutor() 
    ); 
} 

System.out.println("Product List : " + products); // Not printing correct values. Sometimes print blank 

他の方法はありますか?

私はMikhail Baksheevの答えに基づいて実装しましたが、今は適切な結果を得ています。 ちょうどひねり。私は実装する必要があるいくつかの余分なロジックがあります。反復がFutureListを設定しながら

public class MyClass { 

    private Integer   productCount; 
    private Integer   stockCount; 
    private ResultSetFuture result; 
} 

- - 私はとしてList<MyClass>代わりのList<ResultSetFuture>とMyClassのを使用することができる場合、私は疑問に思って

ResultSetFuture result = session.executeAsync(query, key.get()); 
MyClass allResult = new MyClass(); 
allResult.setInCount(inCount); 
allResult.setResult(result); 
allResult.setSohCount(values.size() - inCount); 

futuresList.add(allResult); 
+0

「動作しない」の定義は何を実装する必要がありますか?予想される行動の投稿、および実際の行動。 –

+1

あなたはあなたの先物を待っていませんか?あなたは未来の束を作り、すぐに結果の構造を印刷するように見えます。先物のほとんどがまだ飛行中であるため、結果構造にデータが入力されていません。 – RussS

+0

ありがとうございます。訂正とは何ですか?私が参照できるコード例はありますか? – Saurabh

答えて

1

が@RussSが述べたように、すべての先物を待っていないコードが完成されています。

非同期コードを同期する方法はたくさんあります。例えば、CountDownLatchを使用して:

EDIT: をまたコールバックにseparte糸を使用した製品のための同時コレクションを使用してください。

ConcurrentLinkedQueue<Product> products = new ConcurrentLinkedQueue<Product>(); 
final Executor callbackExecutor = Executors.newSingleThreadExecutor(); 
final CountDownLatch doneSignal = new CountDownLatch(/*the Map size*/); 
for (// iterating over a Map) { 
    key = entry.getKey(); 
    String query = "SELECT id,desc,category FROM products where id=?"; 
    ResultSetFuture future = session.executeAsync(query, key); 
    Futures.addCallback(future, 
     new FutureCallback<ResultSet>() { 
      @Override public void onSuccess(ResultSet result) { 
       Row row = result.one(); 
       if (row != null) { 
        Product product = new Product(); 
        product.setId(row.getString("id")); 
        product.setDesc(row.getString("desc")); 
        product.setCategory(row.getString("category")); 

        products.add(product); 
       } 
       doneSignal.countDown(); 

      } 

      @Override public void onFailure(Throwable t) { 
       // log error 
       doneSignal.countDown(); 
      } 
     }, 
     callbackExecutor 
    ); 
} 

doneSignal.await();   // wait for all async requests to finish 
System.out.println("Product List : " + products); 

もう一つの方法は、例えば、リスト内のすべての先物を収集し、グアバのFutures.allAsListで単一の将来として、すべての結果を待つことである。

List<ResultSetFuture> futuresList = new ArrayList<>(/*Map size*/); 
     for (/* iterating over a Map*/) { 
      key = entry.getKey(); 
      String query = "SELECT id,desc,category FROM products where id=?"; 
      futuresList.add(session.executeAsync(query, key)); 
     } 

     ListenableFuture<List<ResultSet>> allFuturesResult = Futures.allAsList(futuresList); 
     List<Product> products = new ArrayList<>(); 
     try { 
      final List<ResultSet> resultSets = allFuturesResult.get(); 
      for (ResultSet rs : resultSets) { 
       if (null != rs) { 
        Row row = rs.one(); 
        if (row != null) { 
         Product product = new Product(); 
         product.setId(row.getString("id")); 
         product.setDesc(row.getString("desc")); 
         product.setCategory(row.getString("category")); 

         products.add(product); 
        } 
       } 
      } 
     } catch (InterruptedException | ExecutionException e) { 
      System.out.println(e); 
     } 
     System.out.println("Product List : " + products); 

EDIT 2

ListとMyClassの代わりにListを使うことができるかどうか疑問に思っています

技術的にそうしていますが、この場合にはFutures.allAsListList<MyClass>を渡すことはできませんかMyClassListenableFutureインターフェース

+0

ありがとうございます。私はcassandraでネストされたクエリを実行する際に問題があり、あなたの返信https://stackoverflow.com/questions/45471519/improve-performance-in-cassandra-and-java-collectionsに従っていました。私の製品リストが空になったときに間欠的に問題が発生することがあります。しかし、私がonSuccessメソッドの中にリストを出力すると結果が得られます。私はawait()を使用する場合、メソッドは長い時間がかかります。提案してください。 – Saurabh

+0

@Saurabh、私は私の答えを更新しました –

+0

私は私の質問を編集しました。見てください。 – Saurabh

関連する問題