how to correct stop a thread and avoid leaks
Hello, im running an app that has a class that implements ServletContextListener (Server class), on that class i create a thread of Listener (that implements Runnable) Listener starts a ServerSocket that listen on a port, and in a periodically manner, this app receives a string, parses the string and stores the data inside a database. Flow is 1. receive a tcp connection (syn , syn+ack, ack) 2. receives lines over and over again inside this connections (each line is parsed and stored) Below is the code of Listener class and how i call this class from Server class. What im facing is im not able to stop Listener in a correct way. doing Listener.interrupt() does nothing. How can i safely stop Listener thread Thanks in advance -- //initalize listener Listener = new Thread((Runnable) new Listener(Integer.parseInt(prop.getProperty("listenonport"; if (!Listener.isAlive()) { Listener.setName("ListenerThread"); Listener.setDaemon(true); Listener.start(); } -- package lesi.p1; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import org.apache.log4j.Logger; /** * * @author alz */ public class Listener implements Runnable { private static org.apache.log4j.Logger log = Logger.getLogger(Listener.class); private Socket clientSocket = null; private ServerSocket serverSocket = null; private int listenport = 0; Thread CDRThread = null; public Listener(int port) { this.listenport = port; } @Override public void run() { try { log.debug("About to listen on port: " + this.listenport); serverSocket = new ServerSocket(this.listenport); while (true) { clientSocket = serverSocket.accept(); CDRThread = new Thread((Runnable) new CDRExec(clientSocket)); if (!CDRThread.isAlive()) { CDRThread.setName("CDRThread"); CDRThread.setDaemon(true); CDRThread.start(); } } } catch (IOException e) { log.error("Catcher IOException: ", e); } finally { try { log.info("Closing socket"); serverSocket.close(); } catch (IOException ex) { log.error("Error trying to close port", ex); } if (CDRThread.isAlive()) { log.info("Stopping CDRExec Thread"); CDRThread.interrupt(); } } } class CDRExec implements Runnable { private Socket client = null; public CDRExec(Socket client) { this.client = client; } @Override public void run() { String inputLine = ""; StringBuilder sb = new StringBuilder(); Parser p = null; BufferedReader in = null; log.debug("Thread: " + Thread.currentThread().getId() + " name: " + Thread.currentThread().getName()); try { p = new Parser(); in = new BufferedReader(new InputStreamReader(client.getInputStream())); while (true) { if ((inputLine = in.readLine()) != null) { p.parseCDR(inputLine); } inputLine = null; } } catch (IOException e1) { try { in.close(); } catch (Throwable ignore) { } p = null; } } } } - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: how to correct stop a thread and avoid leaks
If you want to work with threads in tomcat you need to know about the Tomcat org.apache.catalina.LifecycleListener interface. If you implement the interface and register your class within server.xml your class will be notified of Tomcat life cycle events (Start, Stop, etc...). You can then do appropriate things when those events happen. Here is an example method that is the only method in LifecycleListener: public class TomcatServerLifecycleListener implements LifecycleListener { public void lifecycleEvent(LifecycleEvent event) { if(Lifecycle.STOP_EVENT.equals(event.getType())) { //Call a method on your Runnable that will trigger it to exit the Run() method. // (or set a Boolean to stop looping, I've adjusted your code below too; how you // set the flag is up to you) } } } Here is the line to be added to Server.xml to register a class as a listener: So if you created an object like I have above and gave it a static method that allows you to insert an object that needs to be notified of a shutdown event, then you will be able to control your threads properly. You could even have your Runnable implement the LifecycleListener directly and have your registered object keep a list of objects that need to be notified. There are dozens of ways to do this, pick one that works for you. Don't forget to investigate all of the LifecycleEvent types in case you have use for the other options. Bill -Original Message- From: alexis [mailto:alz...@gmail.com] Sent: June 6, 2011 8:10 PM To: Tomcat Users List Subject: how to correct stop a thread and avoid leaks Hello, im running an app that has a class that implements ServletContextListener (Server class), on that class i create a thread of Listener (that implements Runnable) Listener starts a ServerSocket that listen on a port, and in a periodically manner, this app receives a string, parses the string and stores the data inside a database. Flow is 1. receive a tcp connection (syn , syn+ack, ack) 2. receives lines over and over again inside this connections (each line is parsed and stored) Below is the code of Listener class and how i call this class from Server class. What im facing is im not able to stop Listener in a correct way. doing Listener.interrupt() does nothing. How can i safely stop Listener thread Thanks in advance -- //initalize listener Listener = new Thread((Runnable) new Listener(Integer.parseInt(prop.getProperty("listenonport"; if (!Listener.isAlive()) { Listener.setName("ListenerThread"); Listener.setDaemon(true); Listener.start(); } -- package lesi.p1; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import org.apache.log4j.Logger; /** * * @author alz */ public class Listener implements Runnable { private static org.apache.log4j.Logger log = Logger.getLogger(Listener.class); private Socket clientSocket = null; private ServerSocket serverSocket = null; private int listenport = 0; Thread CDRThread = null; public Listener(int port) { this.listenport = port; } @Override public void run() { try { log.debug("About to listen on port: " + this.listenport); serverSocket = new ServerSocket(this.listenport); while (true) { clientSocket = serverSocket.accept(); CDRThread = new Thread((Runnable) new CDRExec(clientSocket)); if (!CDRThread.isAlive()) { CDRThread.setName("CDRThread"); CDRThread.setDaemon(true); CDRThread.start(); } } } catch (IOException e) { log.error("Catcher IOException: ", e); } finally { try { log.info("Closing socket"); serverSocket.close(); } catch (IOException ex) { log.error("Error trying to close port", ex); } if (CDRThread.isAlive()) { log.info("Stopping CDRExec Thread"); CDRThread.interrupt(); } } } class CDRExec implements Runnable { public Boolean keepRunning = true; // !! Shutdown flag! Set to false to exit loop private Socket client = null; public CDRExec(Socket client) { this.client = client; } @Override public void run() { String inputLine = ""; StringBuilder sb = new StringBuilder(); Parser p = null; BufferedReader in = null; log.debug("Thr
Re: how to correct stop a thread and avoid leaks
yes, did that and it's working now. when contextDestroyed is called, i set the bool to false and force the loop out. What i was missing is loop is exited when > if ((inputLine = in.readLine()) != null) this is completed, so, from Server class what i did is Listener.requestStop(); // this causes to take the boolean to false to exit the loop while(Listener.isAlive()) { Thread.sleep(1500); } Causing main thread (Server) to wait, until a new message is processed by the in.ReadLine, then parsed, then exit the loop and close the Listener thread, and then Listener.isAlive() is not true anymore, now it's working perfect. Thanks for the help. On Jun 7, 2011, at 12:33 PM, Bill Miller wrote: > If you want to work with threads in tomcat you need to know about the Tomcat > org.apache.catalina.LifecycleListener interface. If you implement the > interface and register your > class within server.xml your class will be notified of Tomcat life cycle > events (Start, Stop, > etc...). You can then do appropriate things when those events happen. > > Here is an example method that is the only method in LifecycleListener: > public class TomcatServerLifecycleListener implements LifecycleListener > { > public void lifecycleEvent(LifecycleEvent event) > { > if(Lifecycle.STOP_EVENT.equals(event.getType())) > { > //Call a method on your Runnable that will trigger it > to exit the Run() > method. > // (or set a Boolean to stop looping, I've adjusted > your code below too; how > you > // set the flag is up to you) > } > } > } > Here is the line to be added to Server.xml to register a class as a listener: > > > So if you created an object like I have above and gave it a static method > that allows you to insert > an object that needs to be notified of a shutdown event, then you will be > able to control your > threads properly. You could even have your Runnable implement the > LifecycleListener directly and > have your registered object keep a list of objects that need to be notified. > > There are dozens of ways to do this, pick one that works for you. Don't > forget to investigate all of > the LifecycleEvent types in case you have use for the other options. > > Bill > > -----Original Message----- > From: alexis [mailto:alz...@gmail.com] > Sent: June 6, 2011 8:10 PM > To: Tomcat Users List > Subject: how to correct stop a thread and avoid leaks > > Hello, im running an app that has a class that implements > ServletContextListener (Server class), on > that class i create a thread of Listener (that implements Runnable) > > Listener starts a ServerSocket that listen on a port, and in a periodically > manner, this app > receives a string, parses the string and stores the data inside a database. > Flow is > > 1. receive a tcp connection (syn , syn+ack, ack) > 2. receives lines over and over again inside this connections (each line is > parsed and stored) > > Below is the code of Listener class and how i call this class from Server > class. What im facing is > im not able to stop Listener in a correct way. doing Listener.interrupt() > does nothing. How can i > safely stop Listener thread > > > Thanks in advance > > > -- > //initalize listener >Listener = new Thread((Runnable) new > Listener(Integer.parseInt(prop.getProperty("listenonport"; >if (!Listener.isAlive()) { >Listener.setName("ListenerThread"); >Listener.setDaemon(true); >Listener.start(); >} > > -- > > package lesi.p1; > > import java.io.BufferedReader; > import java.io.IOException; > import java.io.InputStreamReader; > import java.net.ServerSocket; > import java.net.Socket; > import org.apache.log4j.Logger; > > /** > * > * @author alz > */ > public class Listener implements Runnable { > >private static org.apache.log4j.Logger log = > Logger.getLogger(Listener.class); >private Socket clientSocket = null; >private ServerSocket serverSocket = null; >private int listenport = 0; >Thread CDRThread = null; > >public Listener(int port) { >this.listenport = port; >} > >@Override >public void run() { >try { >log.debug("About to listen on port: " + this.listenport); >serverSocket = new ServerSocket(this.listenport); > >while (true) { >clientSocket = serverSocket.accept(); >CDRThread = new Thread((Runnable) new CDRExec(cli
Re: how to correct stop a thread and avoid leaks
On 07/06/2011 16:33, Bill Miller wrote: > If you want to work with threads in tomcat you need to know about the Tomcat > org.apache.catalina.LifecycleListener interface. Eh? Why would you need to put Tomcat specific dependencies in a spec compliant Servlet container? The above is simply not true. The OP use of a ServletContextListener is perfectly valid, (even if the rest of the code is a little odd). p signature.asc Description: OpenPGP digital signature
Re: how to correct stop a thread and avoid leaks
On 9 June 2011 09:11, Pid wrote: > Eh? Why would you need to put Tomcat specific dependencies in a spec > compliant Servlet container? The above is simply not true. > > The OP use of a ServletContextListener is perfectly valid, (even if the > rest of the code is a little odd). Is it better to have a separate class that implements the Listener, and sets running = false in the Threads, or just have the thread class implement the listener itself? Or are there not really any pros or cons either way? - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: how to correct stop a thread and avoid leaks
On 09/06/2011 18:44, Calum wrote: > On 9 June 2011 09:11, Pid wrote: >> Eh? Why would you need to put Tomcat specific dependencies in a spec >> compliant Servlet container? The above is simply not true. >> >> The OP use of a ServletContextListener is perfectly valid, (even if the >> rest of the code is a little odd). > > Is it better to have a separate class that implements the Listener, > and sets running = false in the Threads, or just have the thread class > implement the listener itself? If we're talking abstractly, rather than in reference to the OPs code, then for most cases I'd suggest that a ServletContextListener would be best implemented as a thread controller, rather than as a thread. See java.util.concurrent, e.g. Executors.class, ExecutorService.class. The contextInitialized() method of the SCL would create & start the service, configuring threads etc & contextDestroyed() would shut the service down - it's a thread pool manager, so takes care of stopping the threads, if you've implemented them correctly. Remember to catch InterruptedException in each threads run() method and take care to clean up properly & stop the work it does. If you implement a ThreadFactory you can name threads & make your life easier when/if Tomcat complains they don't shutdown properly. p > Or are there not really any pros or cons either way? > > - > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > signature.asc Description: OpenPGP digital signature