我们有一个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 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的产生线程,但另一种方法呢?服务器关闭会发生什么?
答案 0 :(得分:0)
Conceptualy我没有看到从多个线程调用ejb方法的问题(即使你自己创建了线程)。对于ejb容器来说,这将是另一个客户端。
从你的例子来看,你看起来servlet的灵魂目的是启动一堆计时器。如果你可以使用ejb 3.1,那就有java ee标准的方法来做到这一点。
首先是一个在启动时启动计时器的Singleton 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);
}
}