如何创建一个在我的应用程序运行时一直运行的线程

Itt*_*tai 5 java deployment multithreading timeout servlets

编辑:我现在确定问题与包含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();
}
Run Code Online (Sandbox Code Playgroud)

while

ServletContextListener循环被注释,它没有任何实际意义.

当我的应用程序加载时,我需要在后台运行一个线程,并且不断(没有超时)检查某个队列中的对象.当然,一旦有了对象,它就"照顾它们",然后继续检查队列.

目前,我正在实现java.lang.Thread界面,我在应用程序加载时被调用.在其中,我做了一些维护工作并启动了一个我继承的线程run().

这是我的问题开始的地方(或者我认为).在我的java.util.concurrent.TimeOutException方法中,我有一个

while (true) {
    //some code which doesn't put the thread to sleep ever
}
Run Code Online (Sandbox Code Playgroud)

当我尝试将我的应用程序部署到服务器时,我得到了一个ServletContextListener.我究竟做错了什么?

我不能有一个始终运行的线程吗?删除应用程序后,该线程将被我的相应事件停止while (true).

我确实需要能够毫不拖延地检查队列的东西.

非常感谢您的帮助!

编辑:这是堆栈跟踪

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)
Run Code Online (Sandbox Code Playgroud)

我的代码:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

抱歉格式化混乱,但对于我的"缩进代码4个空格"的生命只是对我不起作用编辑:阅读'BlockingQueue'并实现它,但我仍然得到完全相同的异常和堆栈跟踪.更改了上面的代码以反映'BlockingQueue'的使用

ada*_*ost 5

setDaemon

摘要:

  • 将此线程标记为守护程序线程或用户线程.当运行的唯一线程都是守护程序线程时,Java虚拟机将退出.
  • 必须在线程启动之前调用此方法.
  • 此方法首先调用此线程的checkAccess方法,
    不带参数.这可能导致抛出SecurityException(在
    当前线程中).

主题

摘要:在许多情况下,我们真正想要的是创建在应用程序中执行简单的定期任务的后台线程.setDaemon()方法可用于将Thread标记为守护程序线程,当没有其他应用程序线程保留时,该守护程序线程应该被终止并被丢弃.通常,Java解释器继续运行,直到所有线程都完成.但是当守护程序线程是唯一仍然存活的线程时,解释器将退出.


Ser*_*ipc 3

您的代码不会启动新线程,而是在同一线程中运行循环,这就是您在部署时收到超时错误的原因。

要启动线程,您必须调用 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();
}
Run Code Online (Sandbox Code Playgroud)