繁体   English   中英

Java Executor的多线程

[英]Multi threading with Java Executor

我陷入了以下问题。 说,我有一个包含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。 在此过程的最后,我想将所有结果都包含在“向量”列表中。

我一直在响应中得到不一致的结果。 例如,如果我传递带有10个名称的请求,那么我只会得到3个或4个,有时响应中什么也没有。 我期望如果我通过10,那么我会得到10。

有谁知道是什么引起了问题?

任何帮助将不胜感激。

谢谢

简单的解决方案是将调用添加到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)

}

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

这里至少有2个问题。

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

2.您正在同时从所有可运行对象中访问同一Vector对象。 这很可能会导致 ConcurrentModificationExceptions ,或者只是向量中的垃圾内容。 您需要在QueryTask内部的向量上进行手动同步,或者传递一个线程安全的容器来代替,例如 Collections.synchronizedList( new ArrayList() ); ;。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM