Status: solved
我必须制作一个pastebin,因为我必须指出行号。
注意:不使用executorsService或线程池。只是为了理解以这种方式启动和使用线程有什么问题。 如果我使用1个帖子。该应用程序运作完美!
相关链接:
http://www.postgresql.org/docs/9.1/static/transaction-iso.html http://www.postgresql.org/docs/current/static/explicit-locking.html
main app,
http://pastebin.com/i9rVyari
logs
,http://pastebin.com/2c4pU1K8,http://pastebin.com/2S3301gD
我在for循环中启动了许多线程(10)并实例化了一个runnable
类,但似乎我从db
得到了相同的结果(我从db中找到一些字符串,然后更改它)但是 each thread, I get same string
(尽管每个线程都改变了它。)。使用jdbc
postgresql
可能是常见问题?
line 252
and line 223
该链接在db中标记为processed. (true)
。 crawler class
的其他主题也是这样做的。所以当line 252
应该获得链接时。它应该是processed = false
。但我看到所有threads take same link.
当其中一个线程抓取链接时。它使得它被处理=真。其他人则不应抓它。 (得到它)是标记的processed = true。
getNonProcessedLinkFromDB()
会返回未经处理的链接
public String getNonProcessedLink(){ line 645
public boolean markLinkAsProcesed(String link){ line 705
getNonProcessedLinkFromDB
会查看已处理的= false链接并提供其中一个。 limit 1
每个线程的起始间隔为20秒。
在一个线程内。 1或2秒(估计爬行的处理时间)
line 98 keepS threads from grabbing the same url
如果您看到结果。一个线程使它成为现实。还有其他人访问它。 waaaay过了一段时间。
所有线程都是单独的。甚至一个races
。 db在第一个线程处理链接时使链接为true
答案 0 :(得分:2)
这是一个没有提出简明问题的情况。那里有很多代码,你不知道发生了什么。你需要将它分解,以便你能够理解它出错的地方,然后告诉我们。
潜在冲突的一些事情。
我没有阅读日志,因为它们对我没用。
- 编辑评论 - 数据库通常具有事务。在提交之前,您在一个事务中进行的修改在其他事务中不会出现。交易可以回滚。您需要查看获取刚更新的行并查看值是否真的发生了变化。在另一个交易或另一个连接中执行此操作。
20秒的差距看起来只有在进程开始时才会出现。想象一下, Thread1 处理 URL1 和 Thread2 处理 URL2 的情况。他们都在大约同一时间完成。他们都会查找下一个未经处理的网址(例如网址3 )。他们都会开始处理这个Url,因为他们不知道另一个线程已启动它。您需要一个流程来分发Url,可能是您想要查看的队列。
如果您知道哪些线程正在处理哪些URL,则可能会改进日志记录。您还需要一个较小的样本量,这样您就可以了解正在发生的事情。
答案 1 :(得分:0)
尽管这篇文章中帮助者的评论和回应也是正确的。
在crawl()方法体的开头。
synchronized(Crawler.class){
url = getNonProcessedLinkFromDB();
new BasicDAO().markLinkAsProcesed(url);
}
并在crawl()方法体的底部(当它完成处理时):
crawl(nonProcessedLinkFromDB);
实际上解决了这个问题。
标记链接处理为true并获取新链接并让其他线程在当前工作时获取相同链接之间存在差距。
Synchonized block
进一步发挥了作用。
感谢帮助。 " Fuber"在IRC频道上。 Quakenet服务器#java和Freenode服务器## javaee
以及所有支持我的人!