问题描述:

I am using executorsevice in JAVA to execute some threads, let’s say ten threads, number of threads may vary. Each thread is executing a SQL server query. I am using Future and Callable classes to submit the tasks. I am getting the results [using future.get()] once each thread is finished.

Now my requirement is that I need to know the query which is executed by each thread once its result is returned, even if the result is an empty set.

Here is my code:

List<Future<List>> list = new ArrayList<Future<List>>();

int totalThreads = allQueriesWeight.size();

ExecutorService taskExecutor = Executors.newFixedThreadPool(totalThreads);

for (String query : allQueriesWeight) {//allQueriesWeight is an arraylist containing sql server queries

SearchTask searchTask = new SearchTask(query);

Future<List> submit = taskExecutor.submit(searchTask);

list.add(submit);

}

Here is my call function:

@Override

public List<SearchResult> call() throws Exception {

java.sql.Statement statement = null;

Connection co = null;

List<SearchResult> allSearchResults = new ArrayList();

try {

//executing query and getting results

while (r1.next()) {

...

allSearchResults.add(r);//populating array

}

} catch (Exception e) {

Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, e);

} finally {

if (statement != null) {

statement.close();

}

if (co != null) {

co.close();

}

}

return allSearchResults;

}

Here is how I am getting the results:

for (Future<List> future : list) {

try {

System.out.println(future.get().size());

List<SearchResult> sr = future.get();

} catch (InterruptedException ex) {

Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);

} catch (ExecutionException ex) {

Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);

}

}

In this above for loop, I need to identify the query of which the result is returned. I am a newbie and any help/suggestion is highly appreciated.

Thanks.

网友答案:

Alternative 1: You have both the lists in the same order and of same size, so you can simple do as below

for (int i = 0; i < allQueriesWeight.size(); i++) {
    allQueriesWeight.get(i);
    futureList.get(i);
}

Alternative 2: If all the queries are different, you can use a map as shown below but this approach will lose the order of execution.

int totalThreads = allQueriesWeight.size();
Map<String,Future<List>> map = new HashMap<>;
ExecutorService taskExecutor = Executors.newFixedThreadPool(totalThreads);
for (String query : allQueriesWeight) {//allQueriesWeight is an arraylist containing sql server queries
    SearchTask searchTask = new SearchTask(query);
    Future<List> submit = taskExecutor.submit(searchTask);
    map.put(query ,submit );
}

And then iterate the map

for (Entry<String,Future<List>> future : map.) {
    System.out.println("query is:" +map.getKey());
    List<SearchResult> sr = map.getValue().get();

}

Alternative 3 If you want to keep the order, create a class with Future and query as the attributes and then put that class in list

   public class ResultWithQuery {

    private final Future<List<?>> future;
    private final  String query;


    public ResultWithQuery(Future<List<?>> future, String query) {
        this.future = future;
        this.query = query;
    }


    public Future<List<?>> getFuture() {
        return future;
    }


    public String getQuery() {
        return query;
    }

}

And

List<ResultWithQuery > list = new ArrayList<ResultWithQuery >();
    int totalThreads = allQueriesWeight.size();
    ExecutorService taskExecutor = Executors.newFixedThreadPool(totalThreads);
    for (String query : allQueriesWeight) {//allQueriesWeight is an arraylist containing sql server queries
        SearchTask searchTask = new SearchTask(query);
        Future<List> submit = taskExecutor.submit(searchTask);
        list.add(new ResultWithQuery (submit, query));
    }

And iterate the list

for (ResultWithQuery resQuery: list) {
        try {
            resQuery.getQuery();
            List<SearchResult> sr = resQuery.getFuture.get();
        } catch (InterruptedException ex) {
            Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ExecutionException ex) {
            Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
相关阅读:
Top