我需要一个Web / JavaEE容器中的线程来在同一个JVM中完成AsyncContext objs

时间:2012-04-23 06:53:31

标签: java java-ee servlets java-ee-6 servlet-3.0

我需要Web / JavaEE容器中的一个线程来从外部源获取信息,并在同一个JVM中完成相应的AsyncContext obj。

我希望有一个零添加延迟解决方案,因此排除了定期轮询或计时器。

我可以开始一个线程,但我相信它在Web容器中不受欢迎而且不可移植。的 Q1。是否可以在Java EE容器中以可移植的方式运行线程?

Q2。如果我想在Web容器中运行一个线程,那么“最不可能”的方法是什么? InitializeContext? ExecutorService的? Thread.run?

谢谢!

3 个答案:

答案 0 :(得分:3)

AsyncContext.html#start可能是你能得到的最接近的。

答案 1 :(得分:1)

您可以使用jsr237中的工作管理器在Java EE容器中创建线程。 :http://jcp.org/en/jsr/detail?id=237。如果需要异步作业,则应使用JMS。

答案 2 :(得分:1)

在Java EE 6中,您可以将@Asynchronous注释放在EJB方法上,以使该方法中的工作由特殊的线程池处理:

@Stateless
public class SomeBean {

    @Asynchronous
    public void doSomething() {
        // ...
    }
}

然后在其他地方,注入这个bean并调用doSomething()方法。控制权将立即返回。

@WebServlet("/test")
public class SyncServlet extends HttpServlet {

    @EJB
    private SomeBean someBean;

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        someBean.doSomething();
    }
}

请注意,您可能需要AsyncContext asyncContext = request.startAsync()这样的内容。只有当异步代码仍然需要向响应发送内容时,才会使用它。

如果您需要类似于期间计时器的东西,而不是为响应请求做某事,您可以在单身人士中使用计时器服务:

@Startup
@Singleton
public class SomeTimerBean {

    @Schedule(hour = "*", minute = "*/30", second = "0", persistent = false)
    public void doStuff() {
        // ...
    }
}

您可以使用@TimeOut注释运行一次,而不是定期运行:

@Startup
@Singleton
public class SomeTimerBean {

    @Resource
    private TimerService timerService;

    @Postconstruct
    public void init() {
         timerService.createSingleActionTimer(0, new TimerConfig(null, false));
    }

    @Timeout
    public void doStuff(Timer timer) {
        // ...
    }
}

您可以对此进行修改,例如: SomeTimerBean也可以在其他 bean中调用@Asynchronous方法,基本上也会产生相同的效果。