【问题标题】:Caching Futures and using as they complete缓存期货并在它们完成时使用
【发布时间】:2014-04-19 12:42:55
【问题描述】:

我想知道是否有办法缓存 Futures 以便在它们完成时使用。例如,我有一个主线程,它产生一个从输入流中读取的执行器:

// pseudo code
while(true){
   Callable task = new Callable({
      // setup callable stuff here
      byte[] call(){
        return inputStream.readInBytes();
      }
   });
   Future f = executors.submit(task);
   byte[] b = f.get();  // blocks   Uggh

   // execute of b
   process(b);
}

我想知道是否有办法将期货放入一个集合中,然后在它们完成时进行处理。

// pseudo code
while(true){
   Callable task = new Callable({
      // setup callable stuff here
      byte[] call(){
        return inputStream.readInBytes();
      }
   });
   Future f = executors.submit(task);

   futures.add(f);

   // process bytes as they completed.
   for(Future f: futures){
       if(f.isDone()){   // this doesn't always return valid.  It sometimes throws NPE's
         b = f.get();
         process (b);
       }
   }

}

我已经尝试了第二个代码片段,但它有时会抛出 NPE - 我假设在刚刚启动的线程上调用了“isDone”方法,这是问题所在(猜测)。

有人知道在期货开始完成之前缓存期货的方法吗?现在我的程序连续运行,但我正在寻找优化和加速它的方法。

谢谢

【问题讨论】:

  • 删除了我对Byte 的使用,并将它们改为byte
  • 看看 Java8 中的 CompletableFuture()。这不是最容易实现的技术

标签: java multithreading caching collections concurrency


【解决方案1】:

我不会使用Byte[],而是使用byte[] 或可回收的缓冲区。

如果您想在数据可用时对其进行处理,请在后台线程中进行。

/* loop */ {
   futures.add(new Callable<Result>() {
      // setup callable stuff here
      Result call(){
           byte[] bytes = inputStream.readInBytes();
           return process(bytes);
      }
   });
}

// collect the results
for(Future<Result> f: futures){
    Result result = g.get();
    // do something single thread
}

【讨论】:

  • 不会 Result result = g.get(); 阻止,阻止 for 循环前进吗?还有我们怎么知道result已经完成了?
  • 我刚刚实现了您的代码,它以串行时间运行。没有发生并行处理。
  • @Dan 您是否将 get() 移出循环?如果在 process() 之后无事可做,您可能根本不需要 futures 列表。
  • 如果你需要继续阅读直到没有更多数据,你应该把它放在 Callable 里面,而不是外面。
猜你喜欢
  • 2020-04-25
  • 1970-01-01
  • 2023-03-03
  • 2021-09-21
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
相关资源
最近更新 更多