我正在開發從網站獲取所有鏈接并搜索輸入詞的程式。然后輸入每個鏈接并再次搜索等等。程式執行此操作 3 次(這就是 n 為 3 的原因)。下面的代碼使用遞回方法完成它,并且似乎作業得很好。
但是我想通過使用執行緒來加速這個程序。我該如何實施?據我所知,我可以為此使用 fork/join。
public static void getLinks(String url, Set<String> urls, String word, int n) {
if(url.contains(word)) {
System.out.println("Found: " url);
}
if (urls.contains(url)) {
return;
}
urls.add(url);
if(n<3) {
try {
Document doc = Jsoup.connect(url).get();
Elements elements = doc.select("a[href]");
for (Element element : elements) {
System.out.println(element.absUrl("href"));
getLinks(element.absUrl("href"), urls, word, n 1);
}
} catch (IOException e) {
e.printStackTrace();
}
} else return;
}
public static void main(String[] args) {
Set<String> links = new HashSet<>();
String word = "root";
getLinks("https://example.com", links, word, 0);
}
PS 在最終版本的程式中,與輸入詞匹配的鏈接將列印在 GUI 中。
uj5u.com熱心網友回復:
簡單的方法是提交getLinks到thread poolwhile 迭代Elements:
static ExecutorService executorService = Executors.newCachedThreadPool();
static List<Callable<Object>> todo = new ArrayList<>();
public static void main(String[] args) throws ExecutionException, InterruptedException {
getLinks();
// Wait until all tasks are complete
// Or use invokeAll(collection, timeout) if you want to have a maximum wait time
executorService.invokeAll(todo);
executorService.shutdown();
}
public static void getLinks(String url, Set<String> urls, String word, int n) {
if(n<3) {
try {
for (Element element : new ArrayList<Element>()) {
todo.add(Executors.callable(() -> getLinks()));
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
return;
}
}
uj5u.com熱心網友回復:
您可以使用作業佇列,在其中提交要執行的可運行物件。當您發現鏈接時,您將提交底層頁面的任務以進行爬網。
基本上有作業的生產者和作業的消費者。
https://www.baeldung.com/java-blocking-queue
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/366714.html
上一篇:連接執行緒和發送信號的問題
