【问题标题】:Is a single Java thread better than multiple threading in my scenario?在我的场景中,单个 Java 线程是否比多线程更好?
【发布时间】:2010-08-18 03:33:15
【问题描述】:

我们公司正在运行 Java 应用程序(在单 CPU Windows 服务器上)从 TCP/IP 套接字读取数据并检查特定条件(使用正则表达式),如果找到匹配项,则将数据存储在MySQL 数据库。数据量很大,以每秒 800 条记录的速度读取,大约 70% 的记录将是匹配记录,因此涉及大量数据库写入。该程序使用 LinkedBlockingQueue 来处理数据。生产者类只是读取记录并将其放入队列,消费者类从队列中删除并进行处理。

所以问题是:如果我使用多个消费者线程而不是单个线程会有帮助吗?线程在上述情况下真的有用吗(因为我使用的是单 CPU)?我正在寻找有关如何加快速度(不改变硬件)的建议。

任何建议将不胜感激。谢谢

【问题讨论】:

  • 核心数仅与 CPU 密集型应用程序的线程数有关。我想说绝大多数应用程序不是。
  • 为什么是“LinkedBlockingQueue”?数据是否必须有序地存储在数据库中?
  • 我认为您需要在更改应用程序之前对其进行概要分析。您必须计算 IO(网络数据到达)和 CPU 的利用率百分比。批处理数据以供 cpu 处理是另一种可能的优化。但真正的问题是你真的有性能问题吗?

标签: java multithreading sockets tcp


【解决方案1】:

简单:试试看。

这是您在论点的任何一方争论几个观点的问题之一。但听起来您已经设置了大部分基础设施。只需创建另一个消费者线程,看看是否有帮助。

但是你需要问自己的第一个问题:

什么更好?
如何更好地衡量?

回答这两个问题,然后尝试。

【讨论】:

    【解决方案2】:

    单线程能否跟上传入的数据?数据库能否跟上传出的数据?

    换句话说,瓶颈在哪里?如果您需要使用多线程,请查看并发实用程序中的 Executor 概念(在 Executors 帮助器类中有很多可供选择),因为这将处理您对自己并不特别感兴趣的线程的所有繁琐细节。

    我个人的直觉是,瓶颈是数据库。这里索引和 RAM 有很大帮助,但这是一个不同的问题。

    【讨论】:

      【解决方案3】:

      多线程很有可能会有所帮助,但它很容易测试。使其成为可配置的参数。用 1 个线程、2 个线程、4 个线程、8 个线程等计算每秒可以执行多少个操作。

      【讨论】:

        【解决方案4】:

        首先:
        使用java 5 concurrent api创建您的应用程序是明智的

        如果您的应用程序是围绕ExecutorService 创建的,那么更改使用的线程数相当容易。例如:您可以创建一个线程池,其中线程数由配置指定。所以如果你想改变线程的数量,你只需要改变一些属性。

        关于您的问题:
        - 关于套接字的读取: 据我所知,让两个线程从一个套接字读取数据是没有用的(如果可能的话)。只需使用一个读取套接字的线程,但使该线程中的操作尽可能少(例如读取套接字 - 将数据放入队列 - 读取套接字 - 等)。
        - 关于队列的消费: 明智的做法是按照上面指出的那样构建这部分,这样很容易改变消费线程的数量。
        - 注意:您无法真正预测什么更好,可能还有另一部分是瓶颈,等等。只有监视器/分析才能让您真正了解您的情况。但是如果您的应用程序是如上构造的,那么使用不同数量的线程进行测试真的很容易。

        简而言之:
        - 生产者部分:一个只从套接字读取并放入队列的线程
        - 消费者部分:围绕 ExecutorService 创建,因此很容易调整消费线程的数量
        然后使用分析来定义瓶颈,并使用 A-B 测试来定义系统的最佳消耗线程数

        【讨论】:

          【解决方案5】:

          作为我之前问题的更新:

          我们确实在单消费者线程和多线程(添加 5、10、15 等)之间进行了一些比较测试,并监控了尚未处理的记录的队列大小。差异很小,还有更多.. 在线程数超过 25 后(与运行 5 个线程相比),que 大小变得稍大。使我得出结论,维护线程的开销超过了处理收益。也许这可能是我们的场景所特有的,但只是提到我的观察。

          当然(正如其他人所指出的)瓶颈是数据库。这是通过在 mySQL 中使用多插入语句而不是单插入来处理的。如果我们一开始就没有这个,我们就无法处理这个负载。

          最终结果:我仍然不相信多线程会在处理时间上带来什么好处。也许它还有其他好处......但我只从处理时间因素来看。如果你们中的任何人有相反的经验,请让我们听听。

          再次感谢您的所有意见。

          【讨论】:

          • 糟糕.. 这篇帖子来自 Abdullah,但通过了不同的 ID。
          【解决方案6】:

          在您的场景中,a) 处理最少 b) 只有一个 CPU c) 数据直接进入数据库,添加更多线程不太可能有帮助。换句话说,前端和后端线程是 I/O 绑定的,中间的处理最少。这就是为什么您看不到太多改进的原因。

          你可以做的是尝试有三个阶段:第一个是单线程从套接字中提取数据。第二个是进行处理的线程池。第三个是为数据库输出提供服务的单线程。如果输入速率发生变化,这可能会产生更好的 CPU 利用率,但代价是输出队列的临时增长。如果没有,吞吐量将受到您写入数据库的速度的限制,无论您有多少线程,然后您可以只使用一个读取-处理-写入线程。

          【讨论】:

            猜你喜欢
            • 2014-12-02
            • 1970-01-01
            • 2015-02-03
            • 2012-07-27
            • 2016-09-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多