问题
I need a thread in Web/JavaEE container to fetch information from an external source and complete corresponding AsyncContext objs in same JVM.
I wish to have a zero-added-latency solution, so periodic polling or a timer is ruled out.
I could start a thread but I believe it is frowned upon in a Web container and not portable. Q1. Is it possible to run a thread portably in a Java EE container instead?
Q2. If I want to run a thread in a Web Container anyway, what is the "least of all evil" ways? InitializeContext? ExecutorService? Thread.run?
Thanks!
回答1:
AsyncContext.html#start is probably the closest you can get.
回答2:
You can use work manager in jsr237 for creating a thread in a Java EE container. : http://jcp.org/en/jsr/detail?id=237. If you want an asynchronous job, you should use JMS.
回答3:
In Java EE 6, you can put the @Asynchronous
annotation on an EJB method to have the work in that method be handled by a special thread-pool:
@Stateless
public class SomeBean {
@Asynchronous
public void doSomething() {
// ...
}
}
Then somewhere else, inject this bean and call the doSomething()
method. Control will return immediately.
@WebServlet("/test")
public class SyncServlet extends HttpServlet {
@EJB
private SomeBean someBean;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
someBean.doSomething();
}
}
Note that you might not need something like AsyncContext asyncContext = request.startAsync()
here. You would use this only if the asynchronous code would still need to send something to the response.
If you need something akin to a period timer though, and not do something in response to a request, you can use the timer service in a singleton:
@Startup
@Singleton
public class SomeTimerBean {
@Schedule(hour = "*", minute = "*/30", second = "0", persistent = false)
public void doStuff() {
// ...
}
}
Instead of running periodically, you can also run something like this once using the @TimeOut
annotation:
@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) {
// ...
}
}
You can have variants on this, e.g. SomeTimerBean
can also call an @Asynchronous
method in an other bean as well to basically have the same effect.
来源:https://stackoverflow.com/questions/10276028/i-need-a-thread-in-web-javaee-container-to-complete-asynccontext-objs-in-same-jv