【问题标题】:java application multi-threading design and optimizationjava应用多线程设计与优化
【发布时间】:2014-01-26 15:34:28
【问题描述】:

我设计了一个 java 应用程序。一位朋友建议使用多线程,他声称将我的应用程序作为多个线程运行会显着减少运行时间。

在我的主类中,我进行了一些超出我们范围的操作来填充全局静态变量和哈希映射,以便在整个过程的生命周期中使用。然后我在数组列表的条目上运行应用程序的核心。

        for(int customerID : customers){
        ConsumerPrinter consumerPrinter = new ConsumerPrinter();
        consumerPrinter.runPE(docsPath,outputPath,customerID);
        System.out.println("Customer with CustomerID:"+customerID+" Done");
    }

对于此循环的每次迭代,从机器中获取给定客户的 XML,对其进行解析并在解析后的数据上进行计算。之后,将处理后的结果写入文本文件(读取和写入的数据最多可达几个千兆字节,平均可达 50 MB)。多个迭代可以写入同一个文件。

我应该让这段代码多线程,这样每组客户都被带入一个独立的线程吗?

我如何知道要运行的最佳线程数?

在实现多线程时要考虑哪些最佳实践?

【问题讨论】:

    标签: java multithreading


    【解决方案1】:
    Should I make this piece of code multi-threaded so each group of customers are taken
    in an independent thread?
    

    是的,多线程将节省您的处理时间。在您的列表上进行迭代时,您可以在每次迭代时生成新线程并在其中进行客户处理。但是,如果两个客户处理需要对同一资源进行操作,则您需要进行适当的同步,您必须同步该操作以避免可能的竞争条件或内存不一致问题。

    How can I know the most optimal number of threads to run?
    

    如果不实际分析具有不同线程数的 n 个客户的处理时间,您就无法真正做到。这将取决于您的处理器拥有的内核数量,以及每个客户正在进行的实际处理。

    What are the best practices to take into consideration when implementing multi-threading?
    

    首要条件是您必须拥有多个内核,并且您的操作系统必须支持多线程。目前几乎每个系统都这样做,但这是一个很好的研究标准。其次,您必须分析所有可能导致race condition 的情况。您知道将在多个线程之间共享的所有资源必须是thread-safe。此外,您还必须注意memory inconsistency issues 的可能机会(将您的变量声明为volatile)。最后,在您实际运行测试用例之前,您无法预测或分析某些内容,例如 deadlocks(需要分析线程转储)或 memory leaks(需要分析堆转储)。

    【讨论】:

      【解决方案2】:

      多线程的想法是将一些繁重的进程变成另一个,比如说......“内存块”。

      任何 UI 更新都必须在主/默认线程上完成,例如打印消息或膨胀视图。您可以要求应用程序绘制位图、从 Internet 下载图像或大量验证/循环块以在单独的线程上运行它们,想象您正在创建第二个短寿命应用程序来为您处理这些任务。

      请记住,您可以要求应用在另一个线程上下载/绘制图像,但您必须在主线程的屏幕上打印此图像。

      这通常用于在单独的线程上加载大位图,进行数学计算以调整此大图像的大小,然后在主线程上向用户膨胀/打印/绘画/显示该图像的较小版本。

      在你的情况下,我不知道 runPE() 方法有多重,我不知道它的作用,你可以尝试为他创建另一个线程,但其余的应该在主线程上,它是你的 UI 的主要进程。

      您可以通过放置“ConsumerPrinter consumerPrinter = new ConsumerPrinter();”来优化您的循环在“for(...)”之前,因为它不会动态改变,你可以在循环中删除它以避免每次循环重新启动时创建相同的对象:)

      【讨论】:

        【解决方案3】:

        虽然可以使用直接的 java 多线程 (java.util.concurrent),正如其他答案所讨论的那样,但也要考虑多线程的替代编程方法,例如 actor model。 Actor 模型仍然在底层使用线程,但很多复杂性由 Actor 框架处理,而不是由程序员直接处理。此外,由于创建使用 Actor 模型的程序的方式,很少(或不需要)在线程之间同步共享状态的原因。

        请参阅Which Actor model library/framework for Java?,了解流行的演员模型库的讨论。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-06
          • 1970-01-01
          相关资源
          最近更新 更多