如何创建一个我的应用程序正在运行的线程 [英] How to create a thread that runs all the time my application is running

查看:157
本文介绍了如何创建一个我的应用程序正在运行的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:
我现在确定问题是与
while(true)循环相关的所有其他命令,因为我' ve已经评论了它,应用程序没有附加的例外部署。我不确定这是多么重要,但我的 ServletContextListener 实现如下所示:

I'm now sure that the problem is related to the while (true) loop holding all other commands as I've commented it out and the application deploys without the attached exception. I'm not sure how much it is important but my ServletContextListener implementation looks like this:


public class BidPushService实现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 循环被注释,它没有什么意义。

So now the thread is run when the app is deployed but because the while loop is commented it has no real meaning.

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

I need to have a thread run in the background when my application loads and constantly (without a timeout) check a certain queue for objects. Of course, once there are objects, it "takes care of them" and then continues to check the queue.

目前,我正在执行 ServletContextListener 界面,我在应用程序加载时被调用。在其中,我做了一些维护的东西,并启动了一个从 java.lang.Thread 继承的线程。

Currently, I'm implementing the ServletContextListener interface and I'm being called when the app loads. In it, I do a few maintenance things and start a thread which I inherited from java.lang.Thread.

这是我的问题开始的地方(或者我认为)。在我的 run()方法中,我有一个

Here is where my problem begins (or so I think). In my run() method, I have a

while (true) {
    //some code which doesn't put the thread to sleep ever
}

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

When I try to deploy my app to the server I get a java.util.concurrent.TimeOutException. What am I doing wrong?

我不能有一个总是运行的线程?当应用程序被删除时,线程被我的 ServletContextListener 中的相应事件阻止。

Can't I have a thread which is always running? When the app is removed, that thread is stopped by the corresponding event in my ServletContextListener.

我真的需要一些不间断地检查队列的东西。

I really do need something that keeps on checking the queue without delay.

非常感谢任何帮助!

编辑:是堆栈跟踪

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;
    }
}

对不起,格式化混乱,但对于我的生活indent code by 4 spaces只是不适合我
编辑:阅读关于'BlockingQueue'并实现它,但我仍然得到完全相同的异常和堆栈跟踪。更改了上述代码以反映使用'BlockingQueue'

Sorry for the formatting mess but for the life of my "indent code by 4 spaces" just does not work for me Read about 'BlockingQueue' and implemented it, but I'm still getting the exact same exception and stack trace. changed the above code to reflect the use of 'BlockingQueue'

推荐答案

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

Your code does not start a new thread, it runs the loop in the same thread and this is why you are getting a timeout error when deployed.

要启动一个线程,您必须调用start方法,而不是运行方法。 p>

To start a thread you must call the start method, not the run method.

public void contextInitialized(ServletContextEvent sce) {   
//Some init code not relevant, omitted for clarity
  BidPushThread t= new BidPushThread();
  t.setServletContext(sce.getServletContext());
  t.start();// run();
}

这篇关于如何创建一个我的应用程序正在运行的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆