最近,我正在尝试实现一个电子邮件服务,该服务可以同时向每个用户发送电子邮件。我当前的实现方式如下:
Highcharts.chart('container', {
chart: {
events: {
load: function() {
var points = this.series[0].points;
Highcharts.each(points, function(point) {
point.dataLabel.attr({
y: 20
});
});
}
}
},
series: [{
color: 'rgba(0,0,0,0)',
zIndex: 0,
dataLabels: {
enabled: true
},
data: [1, 4, 5, 2, 1, 7]
}]
});
经过一些研究,我发现了一种使用Java 8 ExecutorService executor = Executors.newSingleThreadExecutor();
tasks.forEach(executor::execute); // Each task sends an email to an user
executorService.shutdown(); // Reclaim all the resources
方法的新方法。使用这种方法,我做到了:
CompletableFuture.runAsync(...)
现在,对于正确性,可伸缩性以及解决问题的最现代/最新方法,我有些困惑,这是解决问题的最佳方法。
答案 0 :(得分:2)
for key,group in df_grouped:
df_mt = marche_type_jointure_grouped.get_group(key) #we take the corresponding group from the other dataframe
index_har = list(group.heure_arrivee_reelle.index.values) #list of index of actual arrival times from df_grouped referring to key
index_hdp = list(df_mt.heure_debut_periode.index.values) #list of index of beginning time of period from marche_type_jointure_grouped refering to key
for i in index_hdp:
for j in index_har:
if df_mt.heure_fin_periode[i] >= group.heure_arrivee_reelle[j]:
group.temps_trajet_mt[j] = df_mt.temps_trajet_sur_periode[i]
index_har.remove(j) #so that I do not have to compare it again
else:
pass
df_grouped.size().unstack() #so that I can see the result
将异步执行您的任务。
Executor.execute
也异步执行任务,但是另外,返回一个CompletableFuture.runAsync(Runnable, Executor)
对象,您可以使用该对象链接/插入更多相关任务。
(例如,发送电子邮件后,您要向自己发送通知以指示成功:
CompletableFuture
对于您的用例,没有什么不同。
为简单起见,您可以坚持使用第一版代码。
答案 1 :(得分:0)
后一种方法的优势在于,它为您提供了一个CompletableFuture
对象,该对象可用于get
执行该操作的结果,以确保该操作已完成并获取任何异常被动作抛出。
由于您似乎并不在乎这些,我想直接调用执行程序就可以了。
答案 2 :(得分:0)
两个解决方案几乎完全相同-它们都在执行程序上异步执行任务。对于这个小例子,没有什么区别,第一个例子更好,因为它不会创建不必要的CompletableFuture
。
但是,请说您拥有以下代码:
public class EmailSender {
private final Logger log = LoggerFactory.getLogger(EmailSender.class);
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public void sendEmails(Collection<String> emails) {
// make and send emails
Collection<Runnable> tasks = createEmailTasks(emails);
// Send them using the executor and then log a message when all emails have been sent, but how?
}
}
此处Java8和CompletableFuture
为您带来了明显的优势:
// Create futures of all tasks
CompletableFuture[] futures = tasks.stream()
.map(task -> CompletableFuture.runAsync(task, executor))
.toArray(size -> new CompletableFuture[size]);
// Log a message when all tasks have completed
CompletableFuture.allOf(futures)
.thenRunAsync(() -> log.info("Email batch sent successfully"), executor);
您还可以使用CompletableFuture
的任何链接方法(例如.thenRun(Runnable)
或.thenApply(Function<ReturnValue, NewReturnValue>)
(如果您的任务具有返回值)来处理单个任务。
因此,对于您当前的示例来说,这并不重要,但是使用CompletableFuture
更加灵活并且可以面向未来。