【问题标题】:FutureTask and Callable usageFutureTask 和 Callable 用法
【发布时间】:2012-11-30 11:17:54
【问题描述】:

我有一个要实现的功能,我正在考虑使用 FutureTask 和可调用的 calsses。只是想验证我是否可以使用它,以及在这种情况下使用这些类是否正确。 这里是:我正在使用 struts spring hibernate 开发一个 Web 应用程序。我必须上传一个包含大约 40 列/字段和大约 1000 行的 excel/.csv/.txt 类型的文件。我必须处理该行的每一行和每个字段。这将包括以下子任务:

  1. 从单元格/字段中获取数据
  2. 验证 maxlenght 、required 等数据。
  3. 如果该行不符合特定条件,则丢弃该行。
  4. 为每一行创建一个 VO 并用数据填充一个 VO
  5. 存储 VO。

所以,我正在考虑为每个行处理使用未来的任务以使其成为多线程。我面临的问题是如何等待所有任务完成,因为我想发送带有最终结果的响应。只是我想让处理速度更快,而不是实际的响应时间。

【问题讨论】:

  • 考虑使用倒计时锁存器,随着每个任务完成,然后可以指示,然后一旦所有任务都完成,那么您的执行主线程可以继续。我应该想象一下(除非每一行都需要相当长的时间才能完成),线程和任何锁争用都会使您的处理速度比单个线程完成所有工作要慢......
  • 即使我的处理器是多核的也会让它变慢
  • 你应该先尝试一下,如果有问题你应该问。有大量网站可供学习使用。你可以参考 Brain Goetz 的 Java Concurrency in Practice
  • @Narendra Pathai:典型的印度人的反应。如果我知道我会采取的方法。如果有任何问题,我会问具体问题。如果您知道答案,那么请帮助我,否则本次讨论中不需要您。谢谢

标签: java multithreading callable futuretask


【解决方案1】:

看起来每行的工作量相当小,因此并行化确实只能增加执行和响应时间。最耗时的操作是存储到数据库中,批量存储所有 1000 行比单独存储每一行​​要快得多。

如果你真的想在并行任务中拆分行处理,那么做少量的任务,大致等于处理器核心的数量(Runtime.availableProcessors())。 在主线程中,声明一个队列(例如,ConcurrentLinkedQueue),并让每个任务将其结果(已处理的行子集)放入该队列。主线程获取结果,当所有的结果都收集完毕(只计算它们),在数据库中存储一个批次。

【讨论】:

    【解决方案2】:

    我将定义一个RecursiveAction 的子类,它将从 excel 表中获取所有行并将它们分解为单行并执行基本案例部分中每一行提到的操作,使用 ForkJoinPoolinvoke() 方法在这个 RecursiveAction 对象上等待操作完成,然后报告它。可以为计算方法本身的基本案例部分中的每一行构建报告。请查看有关如何使用Fork/Join 的文档。

    【讨论】:

    • 我使用的是 jdk 6 而不是 7。从 JDK7 开始就有 Fork/Join 了吧?
    • 啊! Right ForkJoinPool 是从 JDK 7 开始的。
    【解决方案3】:

    考虑

    ExecutorService.invokeAll(Collection<? extends Callable<T>> tasks)
    

    它执行任务并在所有完成后返回一个 Futures 列表。

    【讨论】:

    • 由于每个任务的结果并不有趣,只有它已经完成的事实,使用 Futures 是多余的。 CountdownLatch 就足够了。
    猜你喜欢
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    相关资源
    最近更新 更多