You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "David.Meldrum" <da...@verizon.net> on 2009/04/29 04:52:45 UTC

Extra Threads in background

Running Tomcat 6.0.18  Standalone on Windows XP.

I need a background task which I implemented as a thread that I stated 
in the ContextListerner.  In the contextInitilized() method I create and 
started the background process.  I give it a name and made it a daemon.  
All that works great!  The problem I noticed is that while I only call 
the BackGroundThread.*start()* method once.  I see at least two threads 
running in Tomcat (las seen in Thread dump and looking at it in 
"Probe").  I only instantiate one instance, but Tomcat behaves like it 
is also calling start() again after I return out of the 
ServerContextListener.contextInitialized() method.  Now I can program my 
background  task to be thread safe and avoid conflicts with it's clones, 
but it seems wasteful, and it causes a lot of lock friction.  So my 
question is, why do I see two threads running, when I only started one 
and how can I avoid the duplicate thread?

Before you say why don't you run the task as a separate OS task, I am 
managing a resource (RS232 serial line) that is owned and controlled by 
my Tomcat application, so it must run inside Tomcat.

RE: Extra Threads in background

Posted by Peter Crowther <Pe...@melandra.com>.
> From: David.Meldrum [mailto:david.meldrum@verizon.net]
> My least favorite activity is programming by experiment.

Try Morris dancing sometime ;-).*  Alternatively, enable debugging, connect a suitable debugger and set a breakpoint in the code you want to prevent being called twice?  Depends on the toolset you have available.

                - Peter

* Before I get descended upon by a side of stick-wielding real ale enthusiasts wearing bells, I should probably point out that I've played for, run sound for and danced Morris.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Extra Threads in background

Posted by "David.Meldrum" <da...@verizon.net>.
Pid, Logging the stack trace is an excellent idea!  I already have been 
counting the the number of Thread starts() (run()) and I found it is 
indeed being started again somewhere.  Looks like I need lots of 
experiments.  My least favorite activity is programming by experiment.

-d

Pid wrote:
> David.Meldrum wrote:
>   
>> Running Tomcat 6.0.18  Standalone on Windows XP.
>>
>> I need a background task which I implemented as a thread that I stated
>> in the ContextListerner.  In the contextInitilized() method I create and
>> started the background process.  I give it a name and made it a daemon. 
>> All that works great!  The problem I noticed is that while I only call
>> the BackGroundThread.*start()* method once.  I see at least two threads
>> running in Tomcat (las seen in Thread dump and looking at it in
>> "Probe").  I only instantiate one instance, but Tomcat behaves like it
>> is also calling start() again after I return out of the
>>     
>
> Why not override the start method of your thread and drop a stack trace
> and log message each time it's called? E.g.
>
> some.log(Thread.currentThread().getName() + " in " +
> servletContext.getContextPath() + " Stacktrace:");
> new Throwable().printStackTrace();
>
> You might even throw in an AtomicInteger count to see if how many
> attempts to start are occuring.
>
> p
>
>
>   
>> ServerContextListener.contextInitialized() method.  Now I can program my
>> background  task to be thread safe and avoid conflicts with it's clones,
>> but it seems wasteful, and it causes a lot of lock friction.  So my
>> question is, why do I see two threads running, when I only started one
>> and how can I avoid the duplicate thread?
>>
>> Before you say why don't you run the task as a separate OS task, I am
>> managing a resource (RS232 serial line) that is owned and controlled by
>> my Tomcat application, so it must run inside Tomcat.
>>
>>     
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>   

Re: Extra Threads in background

Posted by Pid <p...@pidster.com>.
David.Meldrum wrote:
> Running Tomcat 6.0.18  Standalone on Windows XP.
> 
> I need a background task which I implemented as a thread that I stated
> in the ContextListerner.  In the contextInitilized() method I create and
> started the background process.  I give it a name and made it a daemon. 
> All that works great!  The problem I noticed is that while I only call
> the BackGroundThread.*start()* method once.  I see at least two threads
> running in Tomcat (las seen in Thread dump and looking at it in
> "Probe").  I only instantiate one instance, but Tomcat behaves like it
> is also calling start() again after I return out of the

Why not override the start method of your thread and drop a stack trace
and log message each time it's called? E.g.

some.log(Thread.currentThread().getName() + " in " +
servletContext.getContextPath() + " Stacktrace:");
new Throwable().printStackTrace();

You might even throw in an AtomicInteger count to see if how many
attempts to start are occuring.

p


> ServerContextListener.contextInitialized() method.  Now I can program my
> background  task to be thread safe and avoid conflicts with it's clones,
> but it seems wasteful, and it causes a lot of lock friction.  So my
> question is, why do I see two threads running, when I only started one
> and how can I avoid the duplicate thread?
> 
> Before you say why don't you run the task as a separate OS task, I am
> managing a resource (RS232 serial line) that is owned and controlled by
> my Tomcat application, so it must run inside Tomcat.
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Extra Threads in background

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: David.Meldrum [mailto:david.meldrum@verizon.net]
> Subject: Re: Extra Threads in background
> 
> I did not call the "destroy()" method because I though it was 
> deprecated and dangerous.

I believe Chris meant the ServletContextListener.contextDestroyed() method, not Thread.destroy(); the latter should never be used.

Your extra thread should not have to wake up more often to check the terminate flag; the code in your contextDestroyed() method should simply interrupt the extra thread, which will then wake up from its sleep() or wait() call.

As far as your having two instances of your extra thread running, your webapp might be getting deployed twice.  Poorly constructed server.xml and context.xml configs can easily cause this.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.



Re: Extra Threads in background

Posted by "David.Meldrum" <da...@verizon.net>.
Well removing the extra <host> element from my server.xml fixed the 
problem and I now only have the one Background thread I intended.  You 
are right, less resources consumed.  I am not sure where I got the idea 
I needed:

>  <Host name="southchurch.ath.cx"  appBase="webapps"
>          unpackWARs="true" autoDeploy="true"
>          xmlValidation="false" xmlNamespaceAware="false">
>      </Host>

Probably read it as an example in a book.

Christopher Schultz wrote:
> Yup: you have two <Host> elements pointing to the same deployment
> directory. All of your webapps are being deployed one for each <Host>.
> Thus, you get two of them. 

> It is. If your thread has a "please die" boolean that it checks, you should simply set that and allow the thread to finish on its own.
>   
This is what I do and it works fine now.  The thread dies very fast.

-d

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Extra Threads in background

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David,

On 5/4/2009 2:41 PM, David.Meldrum wrote:
>      <Host name="southchurch.ath.cx"  appBase="webapps"
>          unpackWARs="true" autoDeploy="true"
>          xmlValidation="false" xmlNamespaceAware="false">
>                  <!--  Access Log Valve turned off
>          <Valve className="org.apache.catalina.valves.AccessLogValve"
>               directory="logs" prefix="b4bc_access_log."
>               suffix=".txt" pattern="common" resolveHosts="false"/>
>               -->
>      </Host>
>      <Host name="localhost"  appBase="webapps"
>          unpackWARs="true" autoDeploy="true"
>          xmlValidation="false" xmlNamespaceAware="false">
>            </Host>

Yup: you have two <Host> elements pointing to the same deployment
directory. All of your webapps are being deployed one for each <Host>.
Thus, you get two of them.

I don't believe you need a second (first, really) <Host> element: just
stick with the "localhost" one. It doesn't look like the two definitions
are different in any way, so simply removing the "southchurch.ath.cx"
one shouldn't affect you at all (except by freeing up a bunch of memory
being used by extra apps being deployed!).

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkn/TiUACgkQ9CaO5/Lv0PB92wCglV6wBgpYooBIpHmvt5UQQnl4
bfcAoIrUft9uZM/ncydZizajLMb9y89H
=btdD
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Extra Threads in background

Posted by "David.Meldrum" <da...@verizon.net>.
This may be the key to duplicate Thread.  I am not really confident in 
my server.xml so here it is.  Note that I have two "hosts" one for 
"localhost" and the other for the domain "southchurch.atx.cx"  Is that 
correct?  Could that cause the application to run twice?

Server.xml----
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.core.AprLifecycleListener" 
SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener 
className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener 
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
      <!-- ******* Added by D.M. for South Church   -->
      <Host name="southchurch.ath.cx"  appBase="webapps"
          unpackWARs="true" autoDeploy="true"
          xmlValidation="false" xmlNamespaceAware="false">
         
          <!--  Access Log Valve turned off
          <Valve className="org.apache.catalina.valves.AccessLogValve"
               directory="logs" prefix="b4bc_access_log."
               suffix=".txt" pattern="common" resolveHosts="false"/>
               -->
      </Host>
      <Host name="localhost"  appBase="webapps"
          unpackWARs="true" autoDeploy="true"
          xmlValidation="false" xmlNamespaceAware="false">
            </Host>
    </Engine>
  </Service>
</Server>
--  end server.xml

I am more confident in the context.xml

Begin context.xml ----
<?xml version="1.0" encoding="UTF-8"?>
<!-- <Context path="/b4bc" docBase="b4bc"
     debug="5" reloadable="true" crossContext="true"> -->
<Context debug="5" reloadable="true" crossContext="true">
   <Resource name="jdbc/b4bcDB" auth="Container"
       type="javax.sql.DataSource"
    maxActive="10" maxIdle="5" maxWait="10000"
    username="b4bc"
    password="cantTellYou"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/b4bc?autoReconnect=true"
    logAbandoned="true"
    removeAbandoned="true"
    removeAbandonedTimeout="60"
    validationQuery="SELECT 1 "  />
    <!--  JDBC Realm definition -->
    <Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
    dataSourceName="jdbc/b4bcDB" localDataSource="true"
    userTable="users" userNameCol="lname" userCredCol="password"
    userRoleTable="roles" roleNameCol="role" />
</Context>
---  End context.xml
>
> As far as your having two instances of your extra thread running, your 
> webapp
> might be getting deployed twice. Poorly constructed server.xml and 
> context.xml
> configs can easily cause this.
>
> - Chuck
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Extra Threads in background

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David,

On 5/1/2009 1:23 PM, David.Meldrum wrote:
> Chris, This is a good point.  What I am discovering is that while I was
> calling a terminate method on the Thread in the
> ContextListener.contextDestroyed() method, my thread lives for quite
> while, because it is sleeping and does not wake up to test the terminate
> flag for several minutes.  My solution was to reduce the sleep time down
> to a few seconds and only really do something every 20 time it wakes
> up.

How does it sleep? Thread.sleep()? What does this thread do? Could you
use synchronized(foo) { foo.wait(); } and foo.notify() instead of
polling? If so, you could send a notify to the lock monitor and wake up
the thread immediately. You could also call yourThread.interrupt, which
should interrupt a Thread.sleep() call.

> This allowed it to discover the terminate flag much sooner.  I did
> not call the "destroy()" method because I though it was deprecated and
> dangerous.

It is. If your thread has a "please die" boolean that it checks, you
should simply set that and allow the thread to finish on its own.

> I noticed that the Probe  application does have a destroy
> Thread  which works, but warns of being dangerous.

I think the problem is with synchronization locks: when you murder a
thread, it doesn't give up its locks which can be a BIG problem. I
suspect your threads hold few (or any) locks so it's probably okay to do
from a profiler or whatever, but it's best to be avoided in your code.

> I am still trying to figure out why a second thread is spawned. Haven't
> gotten to bottom of that issue yet.

You never told us what the stack trace in init() shows. (!)

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkn/TWUACgkQ9CaO5/Lv0PB1nQCgtNogXU+FxWs8EzX71ogJfHov
7jcAn2TPgoLuerPGUh2LhY+1Vz4D1rXs
=lSpl
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Extra Threads in background

Posted by "David.Meldrum" <da...@verizon.net>.
Chris, This is a good point.  What I am discovering is that while I was 
calling a terminate method on the Thread in the 
ContextListener.contextDestroyed() method, my thread lives for quite 
while, because it is sleeping and does not wake up to test the terminate 
flag for several minutes.  My solution was to reduce the sleep time down 
to a few seconds and only really do something every 20 time it wakes 
up.  This allowed it to discover the terminate flag much sooner.  I did 
not call the "destroy()" method because I though it was deprecated and 
dangerous.   I noticed that the Probe  application does have a destroy 
Thread  which works, but warns of being dangerous.

I am still trying to figure out why a second thread is spawned. Haven't 
gotten to bottom of that issue yet.
-d

Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> David,
>
> On 4/28/2009 10:52 PM, David.Meldrum wrote:
>   
>> I need a background task which I implemented as a thread that I stated
>> in the ContextListerner.
>>     
>
> [snip]
>
>   
>> The problem I noticed is that while I only call
>> the BackGroundThread.*start()* method once.  I see at least two threads
>> running in Tomcat (las seen in Thread dump and looking at it in
>> "Probe").
>>     
>
> Are you re-deploying your application at all? If you are only starting
> your thread, you will be starting a new thread for each deployment. So,
> if you re-start your application, a second (or third, or fourth) will be
> created.
>
> Tomcat doesn't kill your application's threads when the app dies. You
> need to end them yourself. Since you already have a ContextListener,
> just add a destroy() method that shuts down the background thread.
>
> Apologies if you're already doing this, but you didn't mention it and I
> figure it's the most likely scenario.
>
> - -chris
>   


Re: Extra Threads in background

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David,

On 4/28/2009 10:52 PM, David.Meldrum wrote:
> I need a background task which I implemented as a thread that I stated
> in the ContextListerner.

[snip]

> The problem I noticed is that while I only call
> the BackGroundThread.*start()* method once.  I see at least two threads
> running in Tomcat (las seen in Thread dump and looking at it in
> "Probe").

Are you re-deploying your application at all? If you are only starting
your thread, you will be starting a new thread for each deployment. So,
if you re-start your application, a second (or third, or fourth) will be
created.

Tomcat doesn't kill your application's threads when the app dies. You
need to end them yourself. Since you already have a ContextListener,
just add a destroy() method that shuts down the background thread.

Apologies if you're already doing this, but you didn't mention it and I
figure it's the most likely scenario.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkn7JAIACgkQ9CaO5/Lv0PBQ/QCgq3ZlezGAiw8F9M9KiVG6lOjD
B8IAniSz5gk9WBZ97jS0pBjtxLp4IUlj
=hYDX
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org