编辑:我现在确定问题与while (true)保存所有其他命令的循环有关, 因为我已将其注释掉,并且在部署应用程序时没有附加的异常。我不确定它有多重要,但是我的ServletContextListener实现看起来像这样:
while (true)
ServletContextListener
public class BidPushService implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce) { //Some init code not relevant, omitted for clarity BidPushThread t= new BidPushThread(); t.setServletContext(sce.getServletContext()); t.run(); }
因此,现在该线程在部署应用程序时运行,但是由于while注释了循环,因此它没有实际意义。
while
当我的应用程序加载时,我需要在后台运行一个线程,并不断(无超时)检查某个对象队列。当然,一旦有了对象,它就会“照顾它们”,然后继续检查队列。
目前,我正在实现ServletContextListener界面,并且在应用加载时会被调用。在其中,我做了一些维护工作,并启动了一个我继承自的线程java.lang.Thread。
java.lang.Thread
这是我的问题开始的地方(或者我认为是这样)。用我的run()方法,我有一个
run()
while (true) { //some code which doesn't put the thread to sleep ever }
当我尝试将我的应用程序部署到服务器时,出现错误消息java.util.concurrent.TimeOutException。我究竟做错了什么?
java.util.concurrent.TimeOutException
我不能一直运行一个线程吗?删除应用程序后,该线程将被my中的相应事件停止ServletContextListener。
我确实确实需要一些可以不延迟地检查队列的东西。
非常感谢您的帮助!
编辑:这是堆栈跟踪
GlassFish: deploy is failing= java.util.concurrent.TimeoutException at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source) at java.util.concurrent.FutureTask.get(Unknown Source) at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishDeployedDirectory(SunAppServerBehaviour.java:710) at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishModuleForGlassFishV3(SunAppServerBehaviour.java:569) at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishModule(SunAppServerBehaviour.java:266) at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModule(ServerBehaviourDelegate.java:948) at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModules(ServerBehaviourDelegate.java:1038) at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:872) at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:708) at org.eclipse.wst.server.core.internal.Server.publishImpl(Server.java:2690) at org.eclipse.wst.server.core.internal.Server$PublishJob.run(Server.java:272) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
我的代码:
public class BidPushThread extends Thread { private ServletContext sc=null; @Override public void run() { if (sc!=null){ final Map<String, List<AsyncContext>> aucWatchers = (Map<String, List<AsyncContext>>) sc.getAttribute("aucWatchers"); BlockingQueue<Bid> aucBids = (BlockingQueue<Bid>) sc.getAttribute("aucBids"); Executor bidExecutor = Executors.newCachedThreadPool(); final Executor watcherExecutor = Executors.newCachedThreadPool(); while(true) { try // There are unpublished new bid events. { final Bid bid = aucBids.take(); bidExecutor.execute(new Runnable(){ public void run() { List<AsyncContext> watchers = aucWatchers.get(bid.getAuctionId()); for(final AsyncContext aCtx : watchers) { watcherExecutor.execute(new Runnable(){ public void run() { // publish a new bid event to a watcher try { aCtx.getResponse().getWriter().print("A new bid on the item was placed. The current price "+bid.getBid()+" , next bid price is "+(bid.getBid()+1)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }; }); } } }); } catch(InterruptedException e){} } } } public void setServletContext(ServletContext sc){ this.sc=sc; } }
抱歉,格式化混乱,但我的“缩进代码4个空格”对我来说不起作用编辑:阅读’BlockingQueue’并实现了它,但是我仍然得到完全相同的异常和堆栈跟踪。更改了上面的代码以反映“ BlockingQueue”的使用
您的代码不会启动新线程,而是在同一线程中运行循环,这就是为什么在部署时遇到超时错误的原因。
要启动线程,您必须调用start方法,而不是run方法。
public void contextInitialized(ServletContextEvent sce) { //Some init code not relevant, omitted for clarity BidPushThread t= new BidPushThread(); t.setServletContext(sce.getServletContext()); t.start();// run(); }