EDIT:
Теперь я уверен, что проблема связана с
while (true)
цикл, содержащий все остальные команды, как я их закомментировал, и приложение развертывается без присоединенного исключения. Я не уверен, насколько это важно, но моя реализация ServletContextListener
выглядит так:
public class BidPushService implements ServletContextListener{</p>
<pre><code>public void contextInitialized(ServletContextEvent sce) {
//Some init code not relevant, omitted for clarity
BidPushThread t= new BidPushThread();
t.setServletContext(sce.getServletContext());
t.run();
}
Итак, теперь поток запускается при развертывании приложения, но поскольку цикл while
прокомментирован, он не имеет реального значения.
Мне нужно запустить поток в фоновом режиме, когда мое приложение загружается и постоянно (без тайм-аута) проверяет определенную очередь на наличие объектов. Конечно, когда объекты есть, они «заботятся о них», а затем продолжают проверять очередь.
В настоящее время я реализую интерфейс ServletContextListener
, и меня вызывают, когда приложение загружается. В нем я делаю несколько вещей по обслуживанию и запускаю поток, унаследованный от java.lang.Thread
.
Вот здесь и начинается моя проблема (или я так думаю). В моем методе run()
у меня есть
while (true) {
//some code which doesn't put the thread to sleep ever
}
Когда я пытаюсь развернуть свое приложение на сервере, я получаю java.util.concurrent.TimeOutException
.
Что я делаю не так?
Не могу ли я иметь поток, который всегда работает? Когда приложение удаляется, этот поток останавливается соответствующим событием в моем 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'