#java #multithreading #swing #selenium-webdriver #java-threads
#java #многопоточность #swing #selenium-webdriver #java-потоки
Вопрос:
Я создаю веб-сканер с Selenium и шаблоном проектирования MVC на Java. Я пытаюсь добиться трех вещей:
-
Чтобы создать n количество потоков в зависимости от длины моей базы данных (sidb), в которой хранятся настройки поиска.
-
Поскольку в моем графическом интерфейсе есть табличная панель с данными, мне нужно, чтобы все потоки завершились, прежде чем продолжить. В противном случае я потеряю некоторые данные, потому что метод 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();
}
}
}
Как правильно это сделать?
Спасибо!
Комментарии:
1. Вероятно, вам следует взглянуть на пул потоков.
Ответ №1:
Небольшие изменения в вашем коде
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 /
Комментарии:
1. может быть какая-то синтаксическая ошибка (записал ее из памяти). прокомментируйте, если вы найдете некоторые.
2. пытался запустить 8 потоков…. кажется, что все запущено… проверено с использованием кода pastebin.com/s1mzuagq
3. Я понял это и реализовал пул потоков, спасибо!