我正在编写一个使用异步EJB 3.1方法来并行执行许多任务的企业Java应用程序。为了支持取消长时间运行的任务,我一直在尝试使用Future接口(interface)。

不幸的是,尽管取消调用返回future.cancel(true),从客户端应用程序调用true似乎对执行任务的bean的 session 上下文没有影响。

我有一个简单的界面:

public interface AsyncInterface
{
    Future<Integer> run() throws Exception;
}

使用如下的bean实现:
@Stateless
@Remote(AsyncInterface.class)
public class AsyncBean
{
    @Resource SessionContext myContext;

    @Asynchronous
    public Future<Integer> run() throws Exception
    {
        Integer result = 0;

        System.out.println("Running AsyncBean");

        while(myContext.wasCancelCalled() == false)
        {
            Thread.sleep(2000);
            System.out.println("Working");
        }

        System.out.println("AsyncBean cancelled");

        return new AsyncResult<Integer>(result);
     }
}

客户端代码很简单:
InitialContext ctx = new InitialContext();
AsyncInterface async = (AsyncInterface)ctx.lookup("AsyncBean/remote");
Future<Integer> future = async.run();

if( future.cancel(true) )
{
     System.out.println("future.cancel() returned true");
}
else
{
     System.out.println("future.cancel() returned false");
}

bean的输出是无尽的“工作”流;它永远不会检测到取消。

如果相关,我将在JBoss Application Server 6.0.0上运行该应用程序。我没有使用Future接口(interface)的取消功能找到很多示例代码,所以我想知道我是否正确使用Future。这种用法看起来正确吗?是否有更好的选项来取消异步EJB方法调用?

最佳答案

回答我自己的问题-我发现JBoss AS 6.0.0不支持可异步调用的调用。

作为替代方案,我将代码重构为使用JMS请求/响应样式消息传递。

消息驱动的bean用于执行异步操作。消息驱动的Bean创建一个临时队列,并通过JMS将队列返回给调用方。这是通过利用JMS消息的ReplyTo字段实现的。

然后,消息驱动bean定期检查临时队列中是否有取消消息​​。

这比@Asynchronous版本要复杂得多,但是它可以在JBoss AS 6.0.0上运行。

07-24 09:47
查看更多