Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并行方法处理_Java_Multithreading - Fatal编程技术网

Java 并行方法处理

Java 并行方法处理,java,multithreading,Java,Multithreading,如何在java中执行异步过程 在我的程序中,有两个过程 通过邮件将通知消息发送给客户 将订单信息添加到数据库中 我想对sendMessage()和addNewOrder()执行并行处理。 实际上,我没有多线程方面的经验 OrderService.java public void addNewOrder(Order order) { mailer.sendMessage(order.getCustomer()); orderDAO.insert(order); } SMTPMai

如何在java中执行异步过程

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

  • 通过邮件将通知消息发送给客户
  • 将订单信息添加到数据库中
  • 我想对
    sendMessage()
    addNewOrder()
    执行并行处理。 实际上,我没有多线程方面的经验

    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吗?因为我的开发环境是

  • JBoss7.1
  • Spring3.0
  • JSF2.0和Primefaces 3.5
  • JPA2.0
  • JBossSeam 2.3

  • 如何做到这一点的想法:

    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();
    }
    

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

    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
    也需要错误处理。(它可能只是在某处记录任何错误。)

    您可以使用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();
        }
    
    //准备可调用项
    类MailerCallable实现可调用{
    顾客;
    公共邮件可调用(客户){
    this.customer=customer;
    }
    @凌驾
    public Void call()引发异常{
    mailer.sendMessage(客户);
    返回null;
    }
    }
    类OrderCallable实现可调用{
    订单;
    公共医嘱可调用(医嘱){
    这个。顺序=顺序;
    }
    @凌驾
    public Void call()引发异常{
    插入(订单);
    返回null;
    }
    }
    //准备遗嘱执行人服务
    ExecutorService=Executors.newFixedThreadPool(2);
    List callables=new ArrayList();
    add(新的MailerCallable(order.getCustomer());
    add(newordercallable(order));
    //执行全部并等待结果
    试一试{
    service.invokeAll(可调用项);
    }
    捕捉(中断异常e){
    e、 printStackTrace();
    }
    
    如果您发布您正在开发的应用程序类型,这会有所帮助。启动应该会有所帮助。虽然这在技术上是正确的,但如果它位于Servlet或web应用程序中的另一种控制器中,则显然是错误的。请注意,OP发布了一个与JBoss和Spring.Thz一起使用的工具,这是您的答案。您对
    JMS
    有什么建议吗?尽可能让我知道你的建议。你到底是如何使用JMS的?我有机会使用它。