Servlets 在从Servlet派生的线程中使用EJB-错误的做法?

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

我们有一个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生成线程,但是反过来呢?服务器关闭时会发生什么?

从概念上讲,我认为从多个线程调用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。还是谢谢你的回答。