多线程问题->完成线程后检索线程结果

时间:2019-04-09 13:57:10

标签: java multithreading

这是我的代码:

List<Object> array= new ArrayList<Object>();
         int i=0;
         ExecutorService pool = Executors.newFixedThreadPool(50);   
         for(String str : strList) {

             LittleDwarfWorker littleDwarfWorker = new LittleDwarfWorker(params including a datasource);

                try {
                    pool.execute(littleDwarfWorker);
                }catch(Exception e) {
                    e.printStackTrace();
                }
                finally{
                     i++;
                    array.add(littleDwarfWorker.getResult());
                    if((i%100)==0) {
                        log.info("Progression :"+i+"/"+listeEan.size());
                    }
                }       
         }
         pool.shutdown();

这是我心爱的小矮人:

    public void run() {
        JdbcTemplate localJdbcTemplate = new JdbcTemplate(this.dataSource);
        //dwarf dig in database to find some diamonds
    }

我的问题是我跑步时array是空的。我猜我的代码格式错误,但是我对使用多线程来查找错误感到不满意。我猜想array.add()指令是在我的线程完成工作之前执行的,因此value为空。

我在寻找什么: 每个线程都有自己的工作程序,当工作程序产生结果时,它会将结果添加到我的数组中。 对我来说,finally将在我的线程从数据库检索信息之后执行。

我在这里Returning value from Thread查看了Submit方法,但不确定如何获取“未来”值。因为如果我的run方法不是无效的,则会出现错误。

1 个答案:

答案 0 :(得分:3)

Java中的ExecutorService无法以这种方式工作。我猜您LittleDwarfWorker implmenets Runnable和getResult()是您的创作。制作是您的工作人员需要使用implements Callable<Object>的Java方法,它使您可以在任务完成后直接获得结果。您还需要一个CompletionService。因此,您首先提交所有任务,然后收集它们的结果。 .take()返回一个Future<V>来保存您的结果,因此它将阻塞直到准备就绪。

ExecutorService executor = Executors.newFixedThreadPool(50);    
CompletionService<Obejct> completionService = new ExecutorCompletionService<> (executor);
for(String str : strList) {
    completionService.submit(new LittleDwarfWorker(...));
}

for ( int i = 0; i < strList.size(); i++ ) {
  try {
    Object result = completionService.take().get();
    // ... do whatever something with the object

  } catch ( InterruptedException | ExecutionException e ) {
    e.printStackTrace();
  }
}

executor.shutdown();