gpt4 book ai didi

Java/GPars - 我的线程池似乎得到 "clogged"

转载 作者:行者123 更新时间:2023-12-02 11:20:21 28 4
gpt4 key购买 nike

我正在做什么:我正在浏览数据库中的公司表...每个公司都有一个文本description字段,并且在该字段内可以有许多超链接(很少超过 4 个)。我想做的是使用 curl 测试这些链接的“不良”响应(通常为 404,但任何非 200 的内容都会引起兴趣)。

顺便说一句,毫无疑问,这对于 Java 和 Groovy 都适用,无论哪种观点的人都可能有兴趣知道 GPars(Groovy 并行性)此处使用的底层线程池类是 ForkJoinPool.

使用 Matcher 使用 Pattern /(https?:.*?)\)/ 收集这些 URL 后,我得到了映射“url”-->“公司名称”的 descripURLs。然后我使用具有大容量的 withPool (显然是因为等待响应的固有延迟),如下所示:

startMillis = System.currentTimeMillis() 
AtomicInteger nRequest = new AtomicInteger()
AtomicInteger nResponsesReceived = new AtomicInteger()
poolObject = null
resultP = withPool( 50 ){ pool ->
poolObject = pool
descripURLs.eachParallel{ url, name ->
int localNRequest = nRequest.incrementAndGet()
Process process = checkURL( url )

def response
try {
//// with the next line TIME PASSES in this Thread...
response = process.text
} catch( Exception e ) {
System.err.println "$e"
}
// NB this line doesn't appear to make much difference
process.destroyForcibly()
nResponses = nResponsesReceived.incrementAndGet()
int nRequestsNowMade = nRequest.get()
if( response.trim() != '200' ) {
println "\n*** request $localNRequest BAD RESPONSE\nname $name url $url\nresponse |$response|" +
"\n$nRequestsNowMade made, outstanding ${nRequestsNowMade - nResponses}"
// NB following line may of course not be printed immmediately after the above line, due to parallelism
println "\nprocess poolSize $pool.poolSize, queuedTaskCount $pool.queuedTaskCount," +
" queuedSubmissionCount? $pool.queuedSubmissionCount"
}
println "time now ${System.currentTimeMillis() - startMillis}, activeThreadCount $pool.activeThreadCount"
}
println "END OF withPool iterations"
println "pool $pool class ${pool.class.simpleName}, activeThreadCount $pool.activeThreadCount"
pool.shutdownNow()
}

println "resultP $resultP class ${resultP.class.simpleName}"
println "pool $poolObject class ${poolObject.class.simpleName}"
println "pool shutdown? $poolObject.shutdown"

def checkURL( url ) {
def process = "curl -LI $url -o /dev/null -w '%{http_code}\n' -s".execute()
// this appears necessary... otherwise potentially you can have processes hanging around forever
process.waitForOrKill( 8000 ) // 8 s to get a reponse
process.addShutdownHook{
println "shutdown on url $url"
}
process
}

我在上述 50 个线程池中观察到,500 个 URL 将需要 20 秒才能完成。我尝试过更小和更大的池,100 个似乎没有什么区别,但 25 个似乎更慢,10 个则需要 40 秒才能完成。对于相同的池大小,每次运行的计时也非常一致。

我不明白的是,Processes 的关闭 Hook 仅在关闭的最后运行......对于所有 500 个Processes!这并不是说机器上挂着 500 个实际进程:使用任务管理器,我可以看到在任何时刻 curl.exe 进程的数量都相对较小。

同时,我从此处的 println 观察到,此处的 Activity 线程计数从 50 开始,但在整个运行过程中逐渐下降,到最后达到 3(通常)。然而...我还可以观察到最终请求仅在运行结束时添加。

这让我想知道线程池是否以某种方式被这些“僵尸”进程的“未完成的业务”“堵塞”......我希望最终的请求(共 500 个)在运行结束前完成。有什么办法可以提前关闭这些进程吗?

最佳答案

Java 和 Groovy 都不支持子 Process 实例上的 addShutdownHook 方法。

唯一的方法addShutdownHook Java 支持的是 Runtime 实例。这添加了一个钩子(Hook)来在 JVM 关闭时运行。

Groovy 增加了便利 addShutdownHook()Object 类,这样您就不必编写 Runtime.getRuntime().addShutdownHook(..),但这不会改变底层机制:这些钩子(Hook)仅在 JVM 关闭时执行。

因为您使用 process.addShutdownHook 添加的闭包很可能保留对 process 实例的引用,所以这些闭包将一直保持 Activity 状态,直到 JVM 关闭(Java 对象,但是不是操作系统进程)

关于Java/GPars - 我的线程池似乎得到 "clogged",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49964063/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com