0

次のようなサーブレットがあります。

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) {
                }
            }
        }

    }
} 

その目的は、サービスを定期的に呼び出すことです。このサーブレットのインスタンスは 1 つだけで、サーバーの起動時に作成されます。MyService は EJB です。

これはどれほど悪いですか?EJB からのスレッドの生成が許可されていないことは知っていますが、その逆はどうでしょうか? サーバーがシャットダウンするとどうなりますか?

4

1 に答える 1

0

概念的には、複数のスレッドから ejb メソッドを呼び出すことに問題はありません (自分でスレッドを作成したとしても)。とりわけ別のクライアントになるejb-containerの場合。

あなたの例から、サーブレットの魂の目的は、一連のタイマーを開始することであるように見えます。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);
    }
}
于 2012-11-28T19:02:15.300 に答える