我如何在java中完成异步进程?
在我的程序中,有两个过程。
我想为sendMessage()
和addNewOrder()
做并行处理。实际上,我没有Multi-Threading
方面的经验。
OrderService.java
public void addNewOrder(Order order) {
mailer.sendMessage(order.getCustomer());
orderDAO.insert(order);
}
SMTPMailer.java
public void sendMessage(Customer customer) {
// send notification message
}
OrderDAO.java
public void insert(Order order) {
// insert order to database
}
我想,insert()
方法需要运行,即使sendMessage()
进程失败。
顺便说一句,我是否应该使用JMS,因为我的开发环境是
发布于 2013-07-29 07:25:21
这是个坏主意。事实上,目前的操作顺序需要改变。您需要先保存到DB,然后通知客户:
public void addNewOrder(Order order) {
orderDAO.insert(order);
mailer.sendMessage(order.getCustomer());
}
为什么?
如果保存订单失败,您做不想向客户发送确认通知!这会误导顾客。他们会认为他们的订单是在完全丢失的情况下下的。
实际上,在订单无法保存的情况下,您需要进行一些错误处理。如果出现错误,应在响应页中向客户发出某种错误通知。错误处理可能不应该在这个方法中,但是应该放在某个地方。
上面说..。
如果您担心在发送电子邮件时请求阻塞时间过长,则可以让另一个线程发送电子邮件。这确实带来了一些风险,通知电子邮件可能会丢失,如果它无法发送。如果你愿意冒这个风险,你甚至应该尝试在保存订单成功的情况下发送电子邮件。如果您这样做,那么这可能是您可以使用的代码的高度简化版本:
public void addNewOrder(Order order) {
orderDAO.insert(order);
Runnable mailRunnable = new Runnable() {
public void run() {
mailer.sendMessage(order.getCustomer())
}
}
new Thread(mailRunnable).start();
}
Thread
类文档是这里,Runnable
是这里。
我不确定闭包方面(捕获mailer
和order
)在这里是否有效。如果不是,分别实现Runnable
,并将它们作为构造函数的参数。Runnable
也需要错误处理。(它可能只是在某个地方记录任何错误。)
发布于 2013-07-29 06:25:56
如何做到这一点:
public void addNewOrder(Order order) {
Thread sendMessageThread = new Thread(new Runnable() {
public void run() {
mailer.sendMessage(order.getCustomer());
}
});
Thread insertOrderThread = new Thread(new Runnable() {
public void run() {
orderDAO.insert(order);
}
});
// Start both threads;
sendMessageThread.start();
insertOrderThread.start();
// wait for them to finish
sendMessageThread.join();
insertOrderThread.join();
}
发布于 2013-07-29 08:40:49
您可以使用ExecutorService来获得更优雅的解决方案:
// prepare the callables
class MailerCallable implements Callable<Void>{
Customer customer;
public MailerCallable(Customer customer){
this.customer = customer;
}
@Override
public Void call() throws Exception {
mailer.sendMessage(customer);
return null;
}
}
class OrderCallable implements Callable<Void>{
Order order;
public OrderCallable(Order order){
this.order = order;
}
@Override
public Void call() throws Exception {
orderDAO.insert(order);
return null;
}
}
// prepare the executor service
ExecutorService service = Executors.newFixedThreadPool(2);
List<Callable<Void>> callables = new ArrayList<Callable<Void>>();
callables.add(new MailerCallable(order.getCustomer()));
callables.add(new OrderCallable(order));
// execute all and wait for the results
try{
service.invokeAll(callables);
}
catch (InterruptedException e){
e.printStackTrace();
}
https://stackoverflow.com/questions/17917232
复制相似问题