首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >并行方法过程

并行方法过程
EN

Stack Overflow用户
提问于 2013-07-29 06:22:32
回答 3查看 183关注 0票数 1

我如何在java中完成异步进程?

在我的程序中,有两个过程。

  1. 通过邮件将通知消息发送给客户。
  2. 将订单信息添加到数据库中。

我想为sendMessage()addNewOrder()做并行处理。实际上,我没有Multi-Threading方面的经验。

OrderService.java

代码语言:javascript
运行
复制
public void addNewOrder(Order order) {
    mailer.sendMessage(order.getCustomer());
    orderDAO.insert(order);
}

SMTPMailer.java

代码语言:javascript
运行
复制
public void sendMessage(Customer customer) {
    // send notification message
}

OrderDAO.java

代码语言:javascript
运行
复制
public void insert(Order order) {
    // insert order to database
}

我想,insert()方法需要运行,即使sendMessage()进程失败。

顺便说一句,我是否应该使用JMS,因为我的开发环境是

  1. JBoss 7.1
  2. 春季3.0
  3. 带有Primefaces 3.5的JSF2.0
  4. JPA2.0
  5. JBoss Seam 2.3
EN

回答 3

Stack Overflow用户

发布于 2013-07-29 07:25:21

这是个坏主意。事实上,目前的操作顺序需要改变。您需要先保存到DB,然后通知客户:

代码语言:javascript
运行
复制
public void addNewOrder(Order order) {
    orderDAO.insert(order);
    mailer.sendMessage(order.getCustomer());
}

为什么?

如果保存订单失败,您做想向客户发送确认通知!这会误导顾客。他们会认为他们的订单是在完全丢失的情况下下的。

实际上,在订单无法保存的情况下,您需要进行一些错误处理。如果出现错误,应在响应页中向客户发出某种错误通知。错误处理可能不应该在这个方法中,但是应该放在某个地方。

上面说..。

如果您担心在发送电子邮件时请求阻塞时间过长,则可以让另一个线程发送电子邮件。这确实带来了一些风险,通知电子邮件可能会丢失,如果它无法发送。如果你愿意冒这个风险,你甚至应该尝试在保存订单成功的情况下发送电子邮件。如果您这样做,那么这可能是您可以使用的代码的高度简化版本:

代码语言:javascript
运行
复制
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这里

我不确定闭包方面(捕获mailerorder)在这里是否有效。如果不是,分别实现Runnable,并将它们作为构造函数的参数。Runnable也需要错误处理。(它可能只是在某个地方记录任何错误。)

票数 2
EN

Stack Overflow用户

发布于 2013-07-29 06:25:56

如何做到这一点:

代码语言:javascript
运行
复制
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();
}
票数 0
EN

Stack Overflow用户

发布于 2013-07-29 08:40:49

您可以使用ExecutorService来获得更优雅的解决方案:

代码语言:javascript
运行
复制
// 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();
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17917232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档