2

我被以下问题困住了。比如说,我有一个包含 1000 个项目的请求,我想利用 Java Executor 来解决这个问题。

这里是主要方法

public static void main(String[] args) {

     //Assume that I have request object that contain arrayList of names
     //and VectorList is container for each request result

     ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
     Vector<Result> vectorList = new Vector<Result();

     for (int i=0;i<request.size();i++) {
          threadExecutor.execute(new QueryTask(request.get(i).getNames, vectorList)
     }

      threadExecutor.shutdown();

      response.setResult(vectorList)

}

这是 QueryTask 类

public QueryTask() implements Runnable {

    private String names;
    private Vector<Result> vectorList;

    public QueryTask(String names, Vector<Result> vectorList) {
          this.names = names;
          this.vectorList = vectorList;
    }

    public void run() {
         // do something with names, for example, query database
         Result result = process names;

         //add result to vectorList
         vectorList.add(result);
    }


}

因此,基于上面的示例,我想为请求中的每个数据创建线程池,同时运行它,并将结果添加到 VectorList。在过程结束时,我希望所有结果都已经在 Vector 列表中。

我在响应中不断得到不一致的结果。例如,如果我通过 10 个名称的请求,我只能返回 3 或 4 个,或者有时响应中什么也没有。我期待如果我通过 10,那么我会得到 10。

有谁知道是什么导致了这个问题?

任何帮助将不胜感激。

谢谢

4

3 回答 3

3

简单的解决方案是添加对 ExecutorService.awaitTermination() 的调用

public static void main(String[] args) {

     //Assume that I have request object that contain arrayList of names
     //and VectorList is container for each request result

     ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
     Vector<Result> vectorList = new Vector<Result();

     for (int i=0;i<request.size();i++) {
          threadExecutor.execute(new QueryTask(request.get(i).getNames, vectorList)
     }

      threadExecutor.shutdown();
      threadExecutor.awaitTermination(aReallyLongTime,TimeUnit.SECONDS);

      response.setResult(vectorList)

}
于 2010-10-21T23:50:02.503 回答
2

您需要替换threadExecutor.shutdown();threadExecutor.awaitTermination();. 调用后,threadExecutor.shutdown()需要调用。前者是一个非阻塞调用,仅启动关闭,而后者是一个阻塞调用,实际上等待所有任务完成。由于您使用的是前者,您可能会在所有任务完成之前返回,这就是为什么您并不总是能取回所有结果。Java API 不太清楚,所以有人对此提出了错误。threadExecutor.awaitTermination()

于 2010-10-21T22:17:44.907 回答
0

这里至少有2个问题。

  1. 在您的主程序中,您关闭了 ExecutorService,然后尝试立即获取结果。执行器服务将异步执行您的作业,因此很有可能您的所有作业都尚未完成。当您调用 response.setResult(vectorList) 时,vectorList 未完全填充。

2. 您在所有可运行文件中同时访问同一个 Vector 对象。这可能会导致ConcurrentModificationExceptions,或者只是破坏向量中的内容。您需要在 QueryTask 内部的向量上手动同步,或者传入一个线程安全的容器,例如Collections.synchronizedList( new ArrayList() );

于 2010-10-21T22:14:50.797 回答