我正在用 Java 中的 Selenium 和 MVC 设计模式构建一个网络爬虫。我正在努力实现三件事:
根据存储搜索设置的数据库 (sidb) 的长度创建 n 个线程。
因为我的 GUI 中有一个带有数据的 TablePanel,所以我需要所有线程完成才能继续。否则我会丢失一些数据,因为 table.refresh() 方法被提前调用。
由于同时运行超过 5 个 Firefox 窗口会使我的计算机速度减慢太多,因此我希望在任何给定时间最多运行 5 个线程。
下面的代码解决了第一个问题,并在某种程度上解决了第二个问题。我必须创建一个令人讨厌的 Thread.sleep() 以防止它过早地在表上运行刷新。
public void runSearchItems() {
for (int i = 0; i < sidb.getSize(); i++) {
final int num = i;
Thread tn = new Thread(new Runnable() {
@Override
public void run() {
if (sidb.getSearhItem().get(num).getFormevent().getDomainBox().equalsIgnoreCase("www.someURL.com") == true) {
String searchField = sidb.getSearhItem().get(num).getFormevent().getSearchField();
int searchCat = sidb.getSearhItem().get(num).getFormevent().getSearchCategory();
boolean defect = sidb.getSearhItem().get(num).getFormevent().isDefectCheck();
boolean region = sidb.getSearhItem().get(num).getFormevent().isRegionCheck();
String arrange = sidb.getSearhItem().get(num).getFormevent().getArrangeBy();
ArrayList<SiteData> ls = wb.searchWebSite(searchField, searchCat, defect, region, arrange);
for (int j = 0; j < ls.size(); j++) {
db.addSiteData(ls.get(j));
}
}
}
});
tn.start();
try {
tn.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
正确的做法是什么?
谢谢!
最佳答案
对代码进行小改动
public void runSearchItems() {
List<Thread> allThreads = new ArrayList<>();
for (int i = 0; i < sidb.getSize(); i++) {
final int num = i;
Thread tn = new Thread(new Runnable() {
@Override
public void run() {
if (sidb.getSearhItem().get(num).getFormevent().getDomainBox().equalsIgnoreCase("www.someURL.com") == true) {
String searchField = sidb.getSearhItem().get(num).getFormevent().getSearchField();
int searchCat = sidb.getSearhItem().get(num).getFormevent().getSearchCategory();
boolean defect = sidb.getSearhItem().get(num).getFormevent().isDefectCheck();
boolean region = sidb.getSearhItem().get(num).getFormevent().isRegionCheck();
String arrange = sidb.getSearhItem().get(num).getFormevent().getArrangeBy();
ArrayList<SiteData> ls = wb.searchWebSite(searchField, searchCat, defect, region, arrange);
for (int j = 0; j < ls.size(); j++) {
db.addSiteData(ls.get(j));
}
}
}
});
allThreads.add(tn);
}
for(Thread t:allThreads)
t.start();
for(Thread t:allThreads)
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
但是,是的,你更适合使用线程池
例如https://howtodoinjava.com/java/multi-threading/java-thread-pool-executor-example/
关于java - 创建 n 个线程,一次最多 5 个 Activity 线程,等待所有线程完成后再继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55778401/