当前位置: 首页 > 知识库问答 >
问题:

获取每个executorservice线程后面的查询

方夜洛
2023-03-14

我使用JAVA中的executorsevice来执行一些线程,比如说十个线程,线程的数量可能会有所不同。每个线程都在执行一个SQL server查询。我正在使用Future和Callable类提交任务。每个线程完成后,我将[使用future.get()]获得结果。

现在我的要求是,我需要知道返回结果后每个线程执行的查询,即使结果是一个空集。

这是我的代码:

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);
    }

这是我的通话功能:

@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;
}

以下是我获得结果的方式:

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);
        }
    }

在上面的for循环中,我需要标识返回结果的查询。我是一个新手,任何帮助/建议都高度赞赏。

谢谢。

共有1个答案

丁正阳
2023-03-14

备选方案1:两个列表的顺序相同,大小相同,因此您可以按如下简单操作

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

备选方案2:如果所有查询都不同,可以使用如下所示的映射,但这种方法将失去执行顺序。

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 );
}

然后迭代映射

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

}

备选方案3如果您想保持顺序,请创建一个具有Future和query属性的类,然后将该类放入列表中

   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;
    }

}

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));
    }

然后迭代列表

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);
        }
    }
 类似资料:
  • 问题内容: 我正在研究用于并行计算JavaSeis.org的软件开发框架。我需要一个强大的机制来报告线程异常。在开发过程中,了解异常来自何处具有很高的价值,因此我想在过度报告方面犯错。我还希望能够在线程中处理Junit4测试。下面的方法是合理的还是有更好的方法? 问题答案: 我不相信在使用时有标准的“钩子”来获取这些异常。但是,如果您需要支持(听起来很合理,假设您使用),则始终可以包装Callab

  • 我使用(全局声明)同时运行多线程。需要一个小时才能完成任务。因此,我需要获得当前运行的线程详细信息,如活动线程,排队线程和完成线程。 但事情是我需要停止在15分钟内发送新的请求到服务器或调用一些方法。 这里shutdown或shutdowNow停止执行器,但不停止这5个线程。这就是问题所在。所以我需要手动杀死那些线程。如何杀死executor服务中手动附加的线程?

  • 假设我有一个Executors静态工厂方法的ExecutorService实例。 如果我从某个线程提交了一个调用,其中RetVal不是线程安全的本地实例化对象,那么当我从同一个线程获得()它时,我需要担心retvals的完整性吗?人们说局部变量是线程安全的,但我不确定当您返回一个本地实例化的对象并从其他线程接收它时,它是否适用。 下面是我的定制实现,我只是为了测试。您可以忽略EType枚举。

  • 问题内容: 假设我有一个利用该框架的应用程序 当我在调试器中运行此应用程序时,将使用以下(默认)名称创建一个线程:。如你所见,这并不是非常有用,而且据我所知,该框架没有提供一种简便的方法来命名已创建的线程或线程池。 那么,如何为线程/线程池提供名称呢?例如,。 问题答案: 你可以提供一个到。工厂将负责创建线程,并将能够为其命名。 引用Javadoc: 创建新线程 使用创建新线程。如果没有另外指定,

  • 在一个实用程序库中,我正在创建一个执行器服务 然后,主线程将向该服务发布一些任务。当主线程完成时,我想关闭Executor服务,以允许应用程序退出。 问题是我只能更改实用程序库中的代码。我考虑的一个选项是使用守护线程。但在发布到该服务的任务完成之前,它会突然关闭。

  • 我从主线程调用了下面的代码,使用ExecutorService池并启动一个线程来处理找到的每个文件。我正在尝试了解当主线程被kill命令终止时ExecutorService的行为。生成的线程会发生什么?一旦完成工作,它们会立即被杀还是终止? 还有没有更好/更安全的方法来编写下面的代码段,特别是如果我在无限循环中运行这部分,例如等待文件被放到输入目录并分配线程来处理它们?在这种情况下,我应该创建一个