У меня есть многопоточная программа, которая отправляет электронные письма моим клиентам.
В моем коде: thread есть проблемы - код просто закройте окно firefox и все.
Я хочу создать этот алгоритм: у потока есть проблемы - окно firefox (+ selenium) просто закрывается (только один поток закрывается, другие потоки должны продолжать работать), получить данные других параметров из моей БД и снова запустить поток с новыми параметрами
И все время должно работать 5-10 потоков без остановки. Если что-то пойдет не так с потоком - окно firefox должно быть закрыто, программа получит другие данные из БД (я создам этот код, это легко) и должна открыть новое окно firefox и продолжить работу с новыми параметрами.
Основной метод:
static String path = "C:\\Users\\Admin\\Desktop\\clients.txt";
static String path_ok = "C:\\Users\\Admin\\Desktop\\clients2.txt";
static Integer numberMail = 1; //id рассылки
static List<User> users = new ArrayList<User>();
YandexConfig config1 = new YandexConfig("login1", "password1", "cookies", port1);
YandexConfig config2 = new YandexConfig("login2", "password2", "cookies", port2);
ExecutorService executor = Executors.newFixedThreadPool(50);
CompletableFuture.runAsync(new DoThread("thread 1", path, path_ok, numberMail, users, config1), executor);
CompletableFuture.runAsync(new DoThread("thread 2", path, path_ok, numberMail, users, config2), executor);
doThread:
class DoThread implements Runnable {
private String threadName;
private Integer numberMail;
private String themeMessage = "Your order";
private String messageDefault = "blabla";
private final List<User> users;
private final String fileWait;
private final String fileOk;
private final YandexConfig config;
DoThread(String threadName, String fileWait, String fileOk, Integer numberMail, List<User> users, YandexConfig config) {
this.threadName = threadName;
this.fileWait = fileWait;
this.fileOk = fileOk;
this.numberMail = numberMail;
this.users = users;
this.config = config;
}
public void run() {
System.out.println("Thread #" + threadName + " started");
while (true) {
try {
auth(threadName, config.login, config.password);
break;
} catch (InterruptedException e) {
System.out.println("Something goes wrong");
e.printStackTrace();
}
}
//another a lot of strings of code
}
}
Вопрос: как я могу перезапустить поток с новыми параметрами на основе моего кода?




Вам нужен способ изменить параметры для следующего потока. Вам нужно предоставить сеттеры для данных, а затем просто запустить другой поток.
class DoThread implements Runnable {
...
void setThreadName(String name) { ... }
void setFileOK(String fileOK) { ... }
}
class UseDoThread {
void f() {
DoThread r = new DoThread(...);
new Thread(r).start();
...
r.setThreadName("?");
r.setFileOK("I think so");
new Thread(r).start();
}
Однако предупреждение: вам нужно будет дождаться завершения потока, прежде чем изменять значения и перезапускать. В противном случае при первом запуске будут использоваться измененные значения, и ваши данные будут существенно повреждены. Вы можете дождаться завершения потока в течение некоторого времени ожидания, проще всего с помощью метода join.
Но если вы можете просто join, то, возможно, вам вообще не выгодно делать это многопоточным.
Лучше всего создать новый экземпляр DoThread и запустить его.
void f() {
new Thread(new DoThread("thread1", ...)).start();
new Thread(new DoThread("thread2", ...)).start();
}
По этой причине одноразовые классы со значениями final больше используются в параллельном программировании. Каждому потоку нужен свой вариант, и если они все работают одновременно, нет смысла пытаться повторно использовать этот тип класса. Таким образом, вы можете объявить все поля в DoThread окончательными, если вы планируете каждый раз создавать новый DoThread.