我正在創建一個Web刮取器來從網絡中提取鏈接和電子郵件。這些鏈接將用於查找新的地方以搜索電子郵件,然後將電子郵件存儲在一個集合中。每個鏈接都會在其自己的線程中傳遞給固定線程池以查找更多電子郵件。我從小開始只尋找10封電子郵件,但由於某種原因,我的代碼返回了大約13封電子郵件。執行多於循環邊界的Java多線程
while (emailSet.size() <= EMAIL_MAX_COUNT) {
link = linksToVisit.poll();
linksToVisit.remove(link);
linksVisited.add(link);
pool.execute(new Scraper(link));
}
pool.shutdownNow();
emailSet.stream().forEach((s) -> {
System.out.println(s);
});
System.out.println(emailSet.size());
雖然我明白,這是可以創建後,我收到10封電子郵件不應pool.shutdownNow()
結束這些線程仍將運行額外的線程?
這是我的線程代碼,如果有幫助。
class Scraper implements Runnable {
private String link;
Scraper(String s) {
link = s;
}
@Override
public void run() {
try {
Document doc = (Document) Jsoup.connect(link).get();
Elements links = doc.select("a[href]");
for (Element href : links) {
String newLink = href.attr("abs:href");
if (!linksVisited.contains(newLink) && !linksToVisit.contains(newLink)) {
linksToVisit.add(newLink);
}
}
Pattern p = Pattern.compile(
"[a-zA-Z0-9_.+-][email protected][a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+");
Matcher matcher = p.matcher(doc.text());
while (matcher.find()) {
emailSet.add(matcher.group());
}
} catch (Exception e) {
//Catch on of the many exceptions Jsoup.connect might throw
// and just let the thread expire.
}
}
}
編輯1:
我的這包括我的第一次,但我使用一個線程安全組和隊列。
Set<String> emailSet = Collections.synchronizedSet(new HashSet());
BlockingQueue<String> linksToVisit = new ArrayBlockingQueue(10000);
Set<String> linksVisited = Collections.synchronizedSet(new HashSet());
final int EMAIL_MAX_COUNT = 10;
ExecutorService pool = newFixedThreadPool(25);
編輯2
計算過,我應該更新我的回答問題所以這裏是我的問題是。
我的列表將從只有一個鏈接開始。第一個鏈接被刪除後,我有一個空列表,不斷創建新的主題,沒有鏈接進行搜索。在列表可以填充之前,我已經創建了數百個線程,但是它們只是減慢系統速度,直到最終崩潰。
這裏是代碼修復,以確保如果沒有鏈接搜索,將不會創建線程。
while (emailSet.size() <= EMAIL_MAX_COUNT) {
if (linksToVisit.size() > 0) {
link = linksToVisit.poll();
linksToVisit.remove(link);
linksVisited.add(link);
pool.execute(new Scraper(link));
//System.out.println("Emails " + emailSet.size());
} else {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(Crawler.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}
EMAIL_MAX_COUNT的值是什麼? – Lyrion
你爲什麼要在網上搜索電子郵件地址?我在這裏看到潛在的惡魔! –
EMAIL_MAX_COUNT是10. – mcb