只是想知道什么是决定何时停止在作为线程多次运行相同程序的单核机器上创建新线程的最佳方法?
线程正在获取Web内容并进行一些处理,这意味着每个线程的加载在线程终止之前不会一直保持不变.
我想有一个监视CPU/RAM负载的线程,如果负载达到某个阈值就停止创建线程,但是如果已经达到某个线程数,也停止创建线程,以确保CPU没有变得超载.
有关哪些技术可以实现这一目标的任何反馈?
非常感谢,弗拉基米尔
通过监视当前进程使用的 CPU 来做到这一点将会很困难。这些数字往往滞后于现实,结果将在很大程度上出现高峰和低谷。问题是你的线程大部分会被 IO 阻塞,并且没有任何好的方法来预测在不久的将来何时可以读取字节。
也就是说,您可以从ThreadPoolExecutor某个最大线程数(对于单个处理器来说,假设为 4)开始,然后每 10 秒左右检查一次平均负载。如果平均负载低于您想要的值,那么您可以调用setMaximumPoolSize(...)更大的值以在接下来的 10 秒内增加负载平均值。您可能需要在每次计算之间轮询 30 秒或更长时间,以平滑应用程序的性能。
您可以使用以下代码来跟踪所有线程的总 CPU 时间。不确定这是否是最好的方法
long total = 0;
for (long id : threadMxBean.getAllThreadIds()) {
long cpuTime = threadMxBean.getThreadCpuTime(id);
if (cpuTime > 0) {
total += cpuTime;
}
}
// since is in nano-seconds
long currentCpuMillis = total / 1000000;
Run Code Online (Sandbox Code Playgroud)
您可以考虑尝试最大化吞吐量,而不是尝试最大化蜘蛛的 CPU 级别。获取每单位时间蜘蛛抓取的页面数量的样本,并增加或减少最大线程数,ExecutorService直到达到最大化。
需要考虑的一件事是使用 NIO 和选择器,这样你的线程总是忙碌而不是总是等待 IO。这是关于 NIO/Selectors 的一个很好的示例教程。您也可以考虑使用Pyronet,它似乎提供了一些围绕 NIO 的良好功能。