我有一个多线程程序,可以将电子邮件发送给我的客户。
在我的代码中:线程遇到了一些麻烦-代码只是关闭了firefox的窗口,仅此而已。
我想创建这些算法:线程有一些麻烦-firefox(+ selenium)窗口刚刚关闭(仅一个线程正在关闭,另一个线程应继续工作),从我的数据库中获取另一个参数数据,并使用新参数再次启动线程< br />
并且所有时间应不间断地工作5-10个线程。如果线程出了点问题-应该关闭Firefox窗口,程序从DB中获取另一个数据(我将创建这些代码,很容易),并且应该打开新的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
}
}
问题是:如何根据我的代码使用新参数重新启动线程?
答案 0 :(得分:0)
您需要一种方法来修改下一个线程的参数。您需要为数据提供setter,然后才启动另一个线程。
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
中的所有字段为最终字段。