【问题标题】:How to cycle through many threads in Java [closed]如何在Java中循环多个线程[关闭]
【发布时间】:2013-03-27 20:29:27
【问题描述】:

为了我们开发网络压力测试工具的项目,我们将数据包泛洪到整个子网。我们有一个 Runnable 类,它接受一个端口和广播地址,并在 while(!Thread.currentThread().isInterrupted) 循环中发送一个特定的数据包。然后我们有一个主类,它遍历每个网络接口和每个可能的端口,并将 Runnable 类添加到具有 1000 个线程固定池的 ExecutorService 中。问题是如果 ExecutorService 等待当前 1000 个线程完成处理,它们永远不会因为它们处于 while 循环中。但是,启动每个线程(65536 * 接口数)会占用太多内存。我们正在寻找一种循环遍历线程的方法,以便它们都有机会运行一段时间并节省内存,同时仍保持较高的网络输出。

【问题讨论】:

  • 我认为我不想为这项工作做出贡献。

标签: java multithreading networking concurrency


【解决方案1】:

我认为您可能会误以为更多的线程总是会带来更高的吞吐量。通常情况并非如此。

您的应用程序可能会受 CPU 限制,或受网卡吞吐量的限制。强制操作系统处理数以万计的线程竞争这些资源不会会增加您的吞吐量。只有当线程大部分时间都在等待一些高容量的外部资源(例如数据库)时,大量线程才会有所帮助。由于您只是在发送数据包并且(可能)对任何响应都不感兴趣,因此没有自然的等待点。

我建议您只使用与处理器和/或网卡一样多的线程(以较小者为准)。

【讨论】:

  • 那么使用一个线程也可以吗?我认为更多的线程会更快,因为当我创建一个每个端口都有超时时间的端口扫描程序时,多个线程大大加快了程序的速度。
  • 这仍然可以是多线程的,特别是因为单个线程的进程会慢得多,阻塞等待来自网络的回复。单线程是一个很好的考虑(因为线程经常被误用),但这里仍然有一个有效的用例......
  • 您使用的是 TCP 数据包还是单播?如果您正在等待 ACK,多线程将提供一些好处。但仅限于极限。他们很快就会互相妨碍。尝试 1、5、10、50 之类的数字并找到最佳位置。
  • 还使用监控工具 dstat (linux)、perfomon (Windows) 并查找 CPU、网络使用情况和上下文切换(大致是线程切换开销)。
【解决方案2】:

与其让每个线程始终运行完成或“永远”运行,不如让线程执行一小部分定义明确的工作,然后将它们重新添加到执行程序。这种高级管理可以通过“控制器”样式的对象来完成,该对象管理将任务重新添加到执行程序队列中,并执行一系列新的步骤。

例如,如果每个任务有 1000 个步骤要重复执行: - 任务 1 运行步骤 1-100,然后通过将自身添加回执行程序队列来完成步骤 101-200 - 任务 2 有机会以类似方式执行(并完成) - 任务 1 现在是队列中的下一个,因此它执行 101-200,然后添加回 201-300 的执行程序队列。 - 以此类推,直到任务 1 结束 - 901-1000 - 然后如果它想继续执行,则再次返回 1-100。

在您的情况下,不同的步骤可能是端口,不同的线程代表不同的广播地址 - 将其分解为您认为合适的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多