我正在构建一个webcrawler,它有两个主要功能,它们都作为线程执行: - 抓取器(抓取网站并从文件中分离链接将它们存储到数据库中)。 - 下载器(根据提取器返回的url下载文件)。
我有一个对象WebSite
,其中包含我想要了解的有关网站的所有信息。现在,我想操纵我的数据库,将链接的状态从等待更改为获取,然后更改为获取。文件从等待到下载再到已下载。
要阻止Fetcher
获取另一个提取者已选择的链接,我已在WebSite
对象中完成此功能:
public synchronized String[] getNextLink(){
//Return the next link from database that has visited set to 0 then change it to -1 to say that it's in-use.
}
我使用此功能为Downloaders
做了同样的事情:
public synchronized String getNextFile(){
//Return the next file from database that has downloaded set to 0 then change it to -1 to say that it's downloading
}
这两种方法都在我的WebSite
对象中,因为如果2个Fetchers正在使用不同的网站,则他们无法在我的数据库中选择相同的行(同样适用于下载程序)。但这两个功能可以同时调用,因为Fetchers
从不选择文件而Downloaders
从不选择链接。
现在同步使用单个锁(每个对象),因此无法同时调用我的两个方法。还有另一个关键字要使用每个对象一个方法锁一次吗?或者我需要编码吗?
答案 0 :(得分:2)
不是将synchronized
关键字应用于隐式使用this
作为锁对象的整个方法,而是可以使用两个独立的锁对象(而任何对象都可以在方法中用作Java中的锁对象。每个锁定对象将独立于其他锁定对象:
private final Object fetcherMutex = new Object();
private final Object downloaderMutex = new Object();
public String[] getNextLink(){
synchronized (fetcherMutex) { /* ... */ }
}
public String[] getNextFile(){
synchronized (downloaderMutex) { /* ... */ }
}