【问题标题】:Download xml page asynccronosly and write on a file in Java?异步下载xml页面并用Java写入文件?
【发布时间】:2015-03-03 07:52:07
【问题描述】:

我必须根据 id 列表(500 万个 id)下载数据。

我想从所有这些 id 下载一个页面,然后将其写入一个文件。有没有办法下载它们并以异步模式写入文件?我已经同步执行此操作,但需要花时间。

这是我的同步代码:

 while ((sCurrentId = inputFile.readLine()) != null) {
     counterLine++;
     WikiLine wikiLine=download(sCurrentId,counterLine);
     if(wikiLine!=null)
          outputFile.append(wikiLine.toString());
 }

救命!!

【问题讨论】:

    标签: java file asynchronous io download


    【解决方案1】:

    您可以使用执行器同时启动多个任务,并使用单独的线程处理所有任务。 您定义一个 Callable 类来读取输入文件,然后使用 Executor 的 submit(Callable) 方法为您的 ID 提交任务。看看ExecutorService。

    【讨论】:

      【解决方案2】:

      您可以让一个线程读取所有行并将它们添加到队列中,然后另一个线程可以读取队列中的所有行并将其写入文件,可能是这样的:

      final SynchronousQueue<String> wikiLines = new SynchronousQueue<>();
      
      Thread fetchXmlThread = new Thread(() -> {
          while ((sCurrentId = inputFile.readLine()) != null) {
              counterLine++;
              WikiLine wikiLine = download(sCurrentId,counterLine);
              if (wikiLine != null)
                   wikiLines.put(wikiLine.toString());
          }
      });
      
      Thread writeToFileThread = new Thread(() -> {
          for(;;) {
              outputFile.append(wikiLines.take());
          }
      });
      
      fetchXmlThread.start();
      writeToFileThread.start();
      

      请注意,即使在 fetchXmlThread 关闭后 writeToFileThread 仍将继续阻塞,因此您应该实现一些东西以停止该线程。这可以通过在线程阻塞时中断线程来完成(由于wikiLines.take()),或者通过可以检查是否还有任何行以及其他线程是否仍在运行的东西来更改for(;;)。

      如果您确实需要超过 2 个线程,您可能需要查看 executors。

      希望这会有所帮助。

      【讨论】:

      • 谢谢,我通过执行者解决了这个问题。而且你的解决方案听起来很棒!谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2016-01-09
      • 1970-01-01
      • 2017-06-07
      • 1970-01-01
      相关资源
      最近更新 更多