Java EJB3.1启动单例后构造方法中长时间运行的线程中出现异常
Hi是一个长时间运行的线程,在构造后启动并定期更新数据库 看起来像这样Java EJB3.1启动单例后构造方法中长时间运行的线程中出现异常,java,glassfish-3,ejb-3.1,Java,Glassfish 3,Ejb 3.1,Hi是一个长时间运行的线程,在构造后启动并定期更新数据库 看起来像这样 public void postconstruct() { Runnable runnable; runnable = new Runnable() { @Override public void run() { int interval = poissonRandomNumber(15); while (true) {
public void postconstruct() {
Runnable runnable;
runnable = new Runnable() {
@Override
public void run() {
int interval = poissonRandomNumber(15);
while (true) {
try {
Map<Account, AccountUpdate> recentUpdates =
simulator.getRecentUpdates(tickDAO, securityDAO);
for (Map.Entry<Account, AccountUpdate> entry : recentUpdates.entrySet()) {
Account account = entry.getKey();
// String realised = getAccountReturn(parts, account);
Account accountByName = accountDAO.findAccountByName(account.getName());
if( accountByName == null )
{
account.setAccountId(null);
accountByName = accountDAO.create(account);
}
int realised = new Random().nextInt(50);
boolean nextBoolean = new Random().nextBoolean();
realised = nextBoolean == true ? realised : -realised;
AccountUpdate accountUpdate = entry.getValue();
accountUpdate.setAccountId(accountByName);
accountUpdate.setDateCreated(new Date());
accountUpdate.setUnRealisedPL(new BigDecimal(realised));
accountUpdateDAO.create(accountUpdate);
}
Thread.sleep(interval);
} catch (Exception ex) {
Logger.getLogger(ApplicationManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
Thread tickThread = new Thread(runnable);
tickThread.start();
正如这篇文章所解释的
EJB规范将管理线程的责任分配给EJB容器。允许企业bean实例创建和管理线程会干扰容器控制其组件生命周期的能力
这意味着在EJB中使用Runnable
,不是一条好路
如果要以给定的频率运行某些代码,可以使用
如果以另一种方式在数据库更新完成时需要运行一些代码,即异步运行,则必须使用其他技术,如,或数据库触发器,或持久性上下文共享/传播,或,具体取决于应用程序的要求。,在JavaEE中,让应用程序代码启动长时间运行的线程是非常糟糕的做法。为什么问题的标题是关于取消部署,而问题是关于启动?如果您的EJB需要定期更新,为什么不使用EJB定时器呢?这是管理EJB内线程的最佳方法(可能也是唯一允许的方法)?另外,请记住在您发布的代码中插入注释/成员实例化。我已经更新了代码以反映完整的方法。我不能使用计时器,因为帐户更新是随机的。
SEVERE: java.lang.NullPointerException
at com.sun.ejb.containers.util.pool.NonBlockingPool.returnObject(NonBlockingPool.java:285)
at com.sun.ejb.containers.StatelessSessionContainer.releaseContext(StatelessSessionContainer.java:602)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2055)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
at $Proxy270.create(Unknown Source)
at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:126)
at java.lang.Thread.run(Thread.java:722)
SEVERE: javax.ejb.EJBException: Attempt to invoke when container is in Undeployed
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1999)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
at $Proxy265.findSecurityBySymbol(Unknown Source)
at ucl.atrade.rnpvms.server.datafeed.AccountUpdateSimulator.getRecentUpdates(AccountUpdateSimulator.java:74)
at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:108)
at java.lang.Thread.run(Thread.java:722)