我用Java编写了一个软件,通过使用代理发送HTTP请求来检查代理是否正常工作.
它从数据库中获取大约30,000个代理,然后尝试检查它们是否可以运行.从数据库收到的代理曾经作为a返回ArrayList<String>,但Deque<String>由于下述原因而被更改为.
程序的工作方式是有一个ProxyRequest对象将IP和端口分别存储为String和int.该ProxyRequest对象具有一种方法isWorkingProxy(),该方法尝试使用代理发送请求并返回boolean是否成功.
此ProxyRequest对象由RunnableProxyRequest调用super.isWorkingProxy()覆盖run()方法的对象包围.根据响应super.isWorkingProxy(),RunnableProxyRequest对象更新MySQL数据库.
请注意,MySQL数据库的更新是synchronized().
它使用FixedThreadPool(在VPS上)在750个线程上运行,但最后,它变得非常慢(卡在~50个线程上),这显然意味着垃圾收集器正在工作.这就是问题.
我尝试了以下方法来改善延迟,它似乎不起作用:
1)使用Deque<String>代理并使用Deque.pop()获取String代理所在的代理.这(我相信),不断Deque<String>变小,这应该改善GC造成的滞后.
2)设置con.setConnectTimeout(this.timeout);,this.timeout = 5000;这样,连接应在5秒内返回结果.如果没有,则线程完成,并且不应再在线程池中处于活动状态.
除此之外,我不知道任何其他方式可以提高性能.
任何人都可以推荐一种方法来提高性能,以避免/停止通过GC线程结束?我知道有一个关于这个问题的Stackoverflow问题(Java线程在处理结束时会慢下来),但我已经尝试了答案中的所有内容并且它对我没用.
感谢您的时间.
代码片段:
循环添加线程到FixedThreadPool:
//This code is executed recursively (at the end, main(args) is called again)
//Create the threadpool for requests
//Threads is an argument that …Run Code Online (Sandbox Code Playgroud)