Java 并行方法处理
如何在java中执行异步过程 在我的程序中,有两个过程Java 并行方法处理,java,multithreading,Java,Multithreading,如何在java中执行异步过程 在我的程序中,有两个过程 通过邮件将通知消息发送给客户 将订单信息添加到数据库中 我想对sendMessage()和addNewOrder()执行并行处理。 实际上,我没有多线程方面的经验 OrderService.java public void addNewOrder(Order order) { mailer.sendMessage(order.getCustomer()); orderDAO.insert(order); } SMTPMai
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吗?因为我的开发环境是
如何做到这一点的想法:
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的?我有机会使用它。