Servlets 在从Servlet派生的线程中使用EJB-错误的做法?
我们有一个servlet,如下所示:Servlets 在从Servlet派生的线程中使用EJB-错误的做法?,servlets,thread-safety,ejb-3.0,Servlets,Thread Safety,Ejb 3.0,我们有一个servlet,如下所示: public class CacheRefresher extends HttpServlet { private static final long START_TIMEOUT = 120*1000; public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); new T
public class CacheRefresher extends HttpServlet {
private static final long START_TIMEOUT = 120*1000;
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
new Thread(new Worker()).start();
}
private class Worker implements Runnable {
public Worker() { }
public void run() {
try {
Thread.sleep(START_TIMEOUT);
} catch (InterruptedException e) {
}
while(true) {
MyService myService = null;
try {
myService = ServiceFactory.getInstance().getMyService();
myService.doSomething();
} catch (Exception ex){
ex.printStackTrace();
}finally {
ServiceFactory.getInstance().releaseMyService(myService);
}
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
}
}
}
}
}
其目的是定期调用服务。这个Servlet只有一个实例,它将在服务器启动时创建。MyService是一个EJB
这有多糟?我知道不允许从EJB生成线程,但是反过来呢?服务器关闭时会发生什么?从概念上讲,我认为从多个线程调用ejb方法没有问题(即使是您自己创建的线程)。对于ejb容器,它将只是其他客户机中的另一个客户机 从您的示例来看,servlet的核心目的似乎是启动一组计时器。如果您可以使用EJB3.1,那么有一种JavaEE标准方法可以做到这一点 首先是一个在启动时启动计时器的单例ejb
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
@Singleton
@Startup
public class SingletonBean {
@EJB
LabBean labBean;
@PostConstruct
public void init() {
long interval = 4000;
long initialExpiration = 2000;
labBean.startTimer(initialExpiration, interval, "MyTimer");
}
}
然后是处理超时的SLSB:
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
@Stateless
public class LabBean {
@Resource
protected TimerService timerService;
@Timeout
public void timeoutHandler(Timer timer) {
String name = timer.getInfo().toString();
System.out.println("Timer name=" + name);
}
public void stopTimer(String name) {
for (Object o : this.timerService.getTimers())
if (((Timer) o).getInfo().toString().startsWith(name)){
((Timer)o).cancel();
}
}
public void startTimer(long initialExpiration, long interval, String name){
stopTimer(name);
TimerConfig config = new TimerConfig();
config.setInfo(name);
config.setPersistent(false);
timerService.createIntervalTimer(initialExpiration, interval, config);
}
}
我知道EJB3.1的计时器,并在其他项目中使用它们,但遗憾的是,这是EJB3.1。还是谢谢你的回答。