【问题标题】:Java threads become sleeping in linuxJava线程在Linux中进入休眠状态
【发布时间】:2012-01-06 00:55:33
【问题描述】:

我正在编写类似“守护程序”的软件,它使用多线程在循环中执行一些操作(登录到某个地方,执行某些操作并注销)。 我的应用程序运行大约 1000-2000 个线程,这些线程可以完成工作。 所以这是我最初的 htop 日志 ~10 分钟:

所以你可以在上面的截图中看到一些线程正在运行(按绿色 R 状态排序)

但过了一段时间后会发生这种情况:

如您所见,只有一三个线程定期运行(似乎系统减慢了线程或使其进入休眠状态)。 应用程序为小时间作业(大约 10 秒到 1 分钟)运行线程,并且在线程死后固定线程池执行器创建新线程来执行相同的作业。 因此,据我了解,它应该始终保持相同的线程执行速度。但它会在约 10-20 分钟后变慢。通常在 htop 中运行的线程最多为 ~500-200-300-100 个线程,每次下降到 ~3-30-60 个线程。但是在这 10-20 分钟之后,只有线程在执行。那么你能告诉我发生了什么以及如何解决这个问题吗?

【问题讨论】:

  • 可能是死锁?另外——如果你使用 2000 个线程,你就会遇到设计问题。你真的应该使用线程池或生产者/消费者模型。
  • @Chris “线程池或生产者/消费者模型”是什么意思?我现在正在使用线程池。
  • 也许他们都在等待什么,这似乎很合理。您是否尝试过转储所有线程堆栈?有一种方法可以向JVM发送信号以转储所有线程的堆栈(我不知道它是什么)。
  • 使用 2000 个线程可能对内存使用效率不高,具体取决于默认堆栈大小 - 您可能会浪费至少 2G 的(虚拟)内存用于线程堆栈。
  • 使用jstack 获取线程的堆栈跟踪。如果有 2000 个线程,这将是一个相当可观的输出。

标签: java linux multithreading threadpool


【解决方案1】:

线程是否在访问 mysql?我看到它以 100% 的速度运行......如果一个线程正在等待 I/O,内核将让它休眠,直到数据准备好。如果它在磁盘上等待,您可能会在平均负载中看到这一点,因此它可能正在等待网络数据(您的套接字等是否正确关闭?您是否被远程连接的任何服务器阻止?是您的远程服务挂了?)或者mysql数据(你的连接池是不是太小了?mysql无法处理负载?)。

【讨论】:

  • 它只使用 mysql 一次(在加载线程之前)。 MySQL 设置为高负载和连接到远程服务器的线程仅等待响应 1 分钟,然后就死了。
猜你喜欢
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 2011-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
相关资源
最近更新 更多