Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用数据库DAO类方法获取的相同值的多个线程_Java_Database_Multithreading_Postgresql_Concurrency - Fatal编程技术网

Java 使用数据库DAO类方法获取的相同值的多个线程

Java 使用数据库DAO类方法获取的相同值的多个线程,java,database,multithreading,postgresql,concurrency,Java,Database,Multithreading,Postgresql,Concurrency,状态:已解决 我必须制作一个粘贴盒,因为我必须指出行号 注意:不使用executorsService或线程池。只是要了解以这种方式启动和使用线程的错误如果我使用1个线程。该应用程序工作完美 相关链接: main应用程序, 日志 我通过实例化一个runnable类在for循环中启动了许多线程(10),但似乎我从db得到了相同的结果(我从db获得了一些字符串,然后对其进行了更改),但通过每个线程,我得到了相同的字符串(尽管每个线程都更改了它)。对于postgresql使用jdbc,通常会出现什么

状态:已解决

我必须制作一个粘贴盒,因为我必须指出行号

注意:不使用executorsService或线程池。只是要了解以这种方式启动和使用线程的错误如果我使用1个线程。该应用程序工作完美

相关链接:

main应用程序,
日志

我通过实例化一个
runnable
类在for循环中启动了许多线程(10),但似乎我从
db
得到了相同的结果(我从db获得了一些字符串,然后对其进行了更改),但通过
每个线程,我得到了相同的字符串(尽管每个线程都更改了它)。对于
postgresql
使用
jdbc
,通常会出现什么问题

line 252

and line 223
链接被标记为
已处理。(正确)
以db为单位。
爬虫类的其他线程也这样做。所以当
第252行时
应该得到一个链接。它应该是
processed=false
。但我看到所有
线程都采用相同的链接。

当其中一个线程对链接进行爬网时。它使它被处理=真。其他人就不应该爬了。(获取它)是否标记为processed=true


getNonProcessedLinkFromDB()
返回未处理的链接

public String getNonProcessedLink(){        line 645
public boolean markLinkAsProcesed(String link){   line 705
getNonProcessedLinkFromDB
将查看是否存在已处理=错误的链接,并给出其中一个链接<代码>限制1
每个线程的起始间隔为20秒。
在一个线程内。1或2秒(估计爬行的处理时间)

如果您看到结果。一个线程使它成为现实。还有一些人可以访问它。过了一段时间就可以了。


所有的线都是分开的。即使是一个
种族
。当第一个线程处理链接时,db使链接成为真的

这不是一个简洁的问题。里面有很多代码,你根本不知道发生了什么。你需要把它分解,这样你才能理解哪里出了问题,然后给我们展示一下

一些潜在冲突的事情

  • 您正在为几乎每个进程打开一个数据库连接。应用程序的正常流程是打开几个连接,进行一些处理,然后关闭它们
  • 您正在处理数据库提交吗?我不记得postres数据库的默认设置是什么,您必须查看它
  • 一个url有三种状态。未处理的,正在处理的,正在处理的。我认为您根本没有处理“正在处理”状态。因为处理过程需要时间并且可能会失败,所以您必须考虑这些情况
我没有读日志,因为它们对我没用

-编辑以供评论- 数据库通常有事务。您在一个事务中所做的修改在提交之前不会在其他事务中看到。事务可以回滚。您需要查看如何获取刚刚更新的行,并查看值是否真的发生了更改。在其他事务或其他连接中执行此操作

20秒的间隔似乎只有在流程启动时才会出现。设想一种情况,Thread1处理URL1Thread2处理URL2。他们两个差不多同时完成。它们都查找下一个未处理的URL(例如URL3)。他们都会开始处理这个Url,因为他们不知道另一个线程已经启动了它。您需要一个进程来分发Url,您可能希望看到的是一个队列


如果您知道哪些线程正在处理哪些URL,日志记录可能会得到改进。你还需要一个较小的样本量,这样你就可以了解正在发生的事情。

尽管帮助者在这篇文章中的评论和回应也是正确的

在crawl()方法体的开头

    synchronized(Crawler.class){
        url = getNonProcessedLinkFromDB();
        new BasicDAO().markLinkAsProcesed(url);
    }
在crawl()方法体的底部(当它完成处理时):

实际上解决了这个问题

将已处理的链接标记为true与获取新链接之间存在着差距,而当前线程正在处理该链接时,其他线程可以获取相同的链接。

同步块
进一步帮助

感谢帮手。IRC频道上的“Fuber”。Quakenet服务器#java和Freenode服务器##javaee


还有所有支持我的人

您正在使用相同的数据库连接吗?我使用
newbasicdao().method()
我也尝试将这些方法设置为
静态的
。或者将它们的调用放入一个
同步化块
,或者使
布尔值
返回为
volatile
。但是没有用。谢谢回复!!!我提到了与该问题相关的确切行号。完整的代码是必要的,以便分析,如果你想。1.多个连接不会造成伤害。这就是DBs的用途。2.db
提交是什么意思?你是说postgres使用
缓存
?我理解你。但是每个线程在开始时有20秒的间隔。抓取一个页面(处理它)大约需要1到5秒钟。@MasoodAhmad尝试阅读数据库中的事务。它是
commit
rollback
的用途。在不知道事务如何工作的情况下,您将无法构建多线程DB应用程序(因为事务是数据库处理并发性的一种方式),多亏了编辑。我做了和你在日志粘贴中说的一样的事情。它显示URL。2.我知道你刚才说的。我甚至在
crawl()
start
处将链接设置为
processed=true
,只是为了确保它在处理开始之前就被标记为
processed
。(即线程拥有链接,其他线程应将其视为进程)。还是。。。。。。sa
    synchronized(Crawler.class){
        url = getNonProcessedLinkFromDB();
        new BasicDAO().markLinkAsProcesed(url);
    }
    crawl(nonProcessedLinkFromDB);