【问题标题】:Scalability guidance for spawning 50 thousand threads生成 50,000 个线程的可扩展性指南
【发布时间】:2015-03-05 20:05:05
【问题描述】:

我有一个 Java 应用程序,它读取包含 SQL 查询的 JSON 文件并使用 JDBC 在数据库上触发它们。

现在我有 5 万个这样的文件,我需要生成 5 万个独立线程来读取每个文件并将它们上传到数据库中。我需要在特定秒后的特定时间产生这些线程。例如当我应该生成这些线程时,我有以下排序登录详细信息的地图。登录详细信息以秒为单位,许多线程将在 0 秒、10 秒、50 秒等时产生

Map<String,Integer> loginMap = new HashMap<>(50000);

我正在使用 ScheduleExecutureService 来安排这些线程我有类似以下的内容

ScheduleExecutureService ses = Executors.newScheduledThreadPool(50000);
for(Map.Entry<String,Integer> entry : loginMap.entrySet()) {
     Integer loginTime = (Integer) entry.getValue();
      ses.schedule(new MyWorker(entry.getKey()),loginTime,TimeUnit.SECONDS);
}

上面的代码适用于几千个小文件,但它不能扩展到 5 万个,而且由于我的工作人员使用 JDBC 连接,数据库连接不足。

即使我在线程的 run 方法中获取连接。这些线程是否开始执行运行,即使它不应该运行?我是多线程新手。

【问题讨论】:

    标签: java multithreading jdbc


    【解决方案1】:

    您不想要 50,000 个线程!每个线程消耗一些资源,特别是用于堆栈空间的 RAM 区域,这可能是 1MB 左右。你有 50GB 的内存吗?

    运行多于内核的线程也没有任何好处。

    这并不意味着您不能将 50,000 个任务和合理数量的与硬件相关的工作线程排队。

    ScheduleExecutureService ses = Executors.newScheduledThreadPool(8); //sensible, though could be derived from acutal hardware capabilities.
    

    【讨论】:

    • 嗨,Wetson,感谢您的回复,我不想创建这么多线程,但我不知道如何根据登录秒数进行安排,例如第 10 秒应生成 100 个线程,第 20 秒应生成 40 个线程,依此类推。
    • 那么你是在登录压力测试吗?看起来不错,就是不能有这么多线程。您无法让 1 台 PC 表现得像数千台一样。它能做的只有这么多。考虑一些替代方案,例如让更多机器同时登录。或者更好的是,研究如何正确地对该领域进行压力测试。
    • 上面的代码不是压力测试工作正常,因为一次所有线程都不会运行,只有线程集合运行。我只是想找到所有登录时间相同的登录线程并触发它们。这是个好主意吗?
    • 是的,只要理解,如果我们限制为 8 个线程,并且 10 个线程同时登录,有些线程会因为工作线程都忙而延迟。
    • 无论如何,您的操作都会延迟。网络堆栈或数据库中会有队列。最终并发级别是处理器核心数。任何高于此的结果都会导致在某处排队。您应该使用连接池,例如10 个连接,这对你来说应该足够了。相应地使用具有 10 个线程的线程池,以便它们可以利用所有这些连接。更多线程会浪费 RAM。
    猜你喜欢
    • 1970-01-01
    • 2020-03-26
    • 2013-01-29
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    相关资源
    最近更新 更多