定时器java不停止显示Netbeans结果时,取消部署的应用程序



我确实创建了一个定时器,当我部署我的应用程序时开始,我注意的是这个定时器在我Undeploy我的应用程序时不停止?

  1. 这是怎么发生的,并在输出netbeans中显示结果?
  2. 我应该重启我的服务器每次我Undeploy我的应用程序?

单例

@Singleton
@Startup
public class StartWhenDeploy {
    private static final int PERIOD = 3000;
    @PostConstruct
    public void init() {
        System.out.println("I will set information to start my task");
        Timer timer = new Timer();
        timer.schedule(new TimerAction(1), new Date(), PERIOD);
    }
}

TimerTask

public class TimerAction extends TimerTask {
    public int nbrUsers;
    public TimerAction(int nbrUsers) {
        this.nbrUsers = nbrUsers;
    }
    @Override
    public void run() {
        System.out.println("This task is planified to execute at " + new Date());
        System.out.println("Creation " + (createUser() ? "------------Success------------" : "------------Failed------------"));
    }
    public boolean createUser() {
        try {
            System.out.println("-------------->" + nbrUsers);
            for (int i = 0; i < nbrUsers; i++) {
                System.out.println("Create user >>>>" + i);
            }
            return true;
        } catch (Exception e) {
            System.out.println("Exception " + e);
            return false;
        }
    }
}

Output netbeans:

中仍然显示这样的结果
...
Infos: This task is planified to execute at Wed Nov 16 14:40:29 GMT+01:00 2016
Infos: -------------->1
Infos: Create user >>>>0
Infos: Creation ------------Success------------
...
有人对这个问题有什么想法吗?

谢谢。

在GlassFish中(一般在JavaEE中),您应该使用EJB规范中的TimerService来进行调度。我假设您正在使用java.util.Timer,它只是在一个单独的线程中运行。GlassFish对这个线程一无所知,所以它不能用undeploy来停止它。

你应该这样重写你的Singleton:

@Singleton
@Startup
public class StartWhenDeploy {
    private static final int PERIOD = 3000;
    // Inject the TimerService into this EJB
    @Resource
    private TimerService timer;
    private TimerAction action;
    @PostConstruct
    public void init() {
        System.out.println("I will set information to start my task");
        // the action object is created before the timer
        action = new TimerAction(1);
        timer.createTimer(new Date(), PERIOD, "My timer");
    }
    // this method will be executed when the timer fires - it needs to wrap your `TimerAction` created once per this singleton instance (`TimerAction` does not have to extend `TimerTask` now)
    @Timeout
    public void runTimerAction() {
        action.run();
    }
}

TimerTask生成一个新线程,它的生命周期不受取消部署应用程序的影响。

一个更好的方法是对@Schedule使用适当的EJB定时器,如下例所示:
@Singleton
@Startup
public class SimpleTimerBean {
    static Logger logger = Logger.getLogger(SimpleTimerBean.class.getCanonicalName());
    @Schedule(hour = "*", minute = "*", second = "*/3", info = "Create user every 3 seconds", timezone = "UTC")
    public boolean createUser() {
        try {
            System.out.println("-------------->" + nbrUsers);
            for (int i = 0; i < nbrUsers; i++) {
                System.out.println("Create user >>>>" + i);
            }
            return true;
        } catch (Exception e) {
            System.out.println("Exception " + e);
            return false;
        }
    }
}

最新更新