我的两个类中有一个进程方法,它接受一个String of Map。
在下面的代码中,我使用的是for循环,它将逐个(顺序)调用我的两个类中的process方法,这很好。
for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
final Map<String, String> response = entry.getPlugin().process(outputs);
System.out.println(response);
}
但是有什么方法可以为此启动两个线程吗?一个线程将调用我的一个类的进程方法,第二个线程将在我的第二个类中调用进程方法?然后在从每个线程获得响应后,我想写入数据库。意味着每个线程都会写入数据库。
此外,每个线程也应该有超时功能。我们将等待每个线程一段指定的时间,这意味着如果其中一个进程方法没有返回一段时间,那么它将获得timedout。
这可以在我的用例中使用吗?如果是的话,有人能为我提供一个如何做到这一点的例子吗?感谢。
任何帮助都将受到赞赏。
答案 0 :(得分:2)
您可以根据需要分配多个线程来创建ExecutorService,例如
ExecutorService executor = Executors.newFixedThreadPool(2)
现在你的for循环中你会做类似
的事情for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
executor.submit(new Runnable () {
public void run() {
final Map<String, String> response = entry.getPlugin().process(outputs);
// write to database
System.out.println(response);
}
}
}
您可能还希望有一个单独的线程来处理所有数据库写入 - 您的runnables会通过BlockingQueue
或其他某些行将结果发送给它
// Three threads: one thread for the database writer, two threads for the plugin processors
final ExecutorService executor = Executors.newFixedThreadPool(3);
final BlockingQueue<Map<String, String>> queue = new LikedBlockingQueue<>();
Future future = executor.submit(new Runnable () {
public void run() {
Map<String, String> map;
try {
while(true) {
// blocks until a map is available in the queue, or until interrupted
map = queue.take();
// write map to database
}
} catch (InterruptedException ex) {
// IF we're catching InterruptedException then this means that future.cancel(true)
// was called, which means that the plugin processors are finished;
// process the rest of the queue and then exit
while((map = queue.poll()) != null) {
// write map to database
}
}
}
}
for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
executor.submit(new Runnable () {
public void run() {
final Map<String, String> response = entry.getPlugin().process(outputs);
// put the response map in the queue for the database to read
queue.offer(response);
}
}
}
// this interrupts the database thread, which sends it into its catch block
// where it processes the rest of the queue and exits
future.cancel(true); // interrupt database thread
// wait for the threads to finish
executor.awaitTermination(5, TimeUnit.MINUTES);