Как воссоздать поток с новыми параметрами?

У меня есть многопоточная программа, которая отправляет электронные письма моим клиентам. В моем коде: 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
    }
}

Вопрос: как я могу перезапустить поток с новыми параметрами на основе моего кода?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
31
1

Ответы 1

Вам нужен способ изменить параметры для следующего потока. Вам нужно предоставить сеттеры для данных, а затем просто запустить другой поток.

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.

Другие вопросы по теме