One suggestion: Perhaps you should try this with some other servlet
containers to see how it behaves there.
On Fri, 18 Aug 2000, Marc Saegesser wrote:
> Actually this approach seems to work. I create a new thread in init that
> does the connection stuff. In doGet() I join to that thread so ensure that
> the initialization stuff is complete before I process a request. I've
> included sample code below called AppTest3.java.
>
> My concern now is that I even though I wrote code that is perfectly valid
> and thread safe in and of itself, it is affected by undocumented (so far as
> I've found) thread synchronization effects in the execution environment.
> I've stumbled across this one problem, but the nasty thing about thread
> synchronization problems is that code that appears to work in the lab may
> fail in the field where execution timings may be different. So now I wonder
> what other problems may exist that I just haven't hit yet.
>
> Is there a documented reason why my original code should not work? Is the
> approach taken in AppTest3.java the correct and supported way to accomplish
> what I want or are the other synchronization issues hidden inside the
> servlet engine environment that might cause this to fail as well?
>
> ----------- AppTest3.java -----------------
> import java.io.*;
>
> import javax.servlet.*;
> import javax.servlet.http.*;
>
> /**
> *
> */
> public class AppTest3 extends HttpServlet implements Runnable
> {
> private WaitTest conn = null;
> private Thread thrdInit = null;
>
> public void init(ServletConfig config) throws ServletException
> {
> super.init(config);
>
> thrdInit = new Thread(this);
> System.err.println("AppTest3: Starting init thread...");
> thrdInit.start();
> }
>
> public void doGet(HttpServletRequest req, HttpServletResponse res) throws
> ServletException, IOException
> {
> if(thrdInit != null){
> try{
> System.err.println("AppTest3.doGet: Waiting for init
>thread to
> complete.");
> thrdInit.join(30000);
> thrdInit = null;
> }catch(InterruptedException e){
> }
> }
> res.setContentType("text/html");
> PrintWriter out = res.getWriter();
> out.println("<html><body><h1>Blah</h1></body></html>");
> }
>
> public void destroy()
> {
> if(conn != null)
> conn.disconnect();
> }
>
> public void run()
> {
> try{
> System.err.println("AppTest3.run: Creating connection.");
> conn = new WaitTest();
> conn.connect();
> System.err.println("AppTest3.run: Connection established.");
> }catch(Exception e){
> System.err.println("AppTest.init: " + e.toString());
> }
> }
> }
> --------------------------------------------
>
> -----Original Message-----
> From: Kumar, Anil [mailto:[EMAIL PROTECTED]]
> Sent: Friday, August 18, 2000 8:54 AM
> To: '[EMAIL PROTECTED]'
> Subject: RE: Thread synchronization problem in init()
>
>
> Hi,
> I feel u try one another method to do this. That u can create a thread
> in init, but don't there wait in init itself by
> writing join, so that thread can die after making the connection and you can
> continue then.
>
> In doGet it's working because I think that itself is different thread , then
> the main............
>
> May this can help u..........
>
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Anil Kumar Phone (Work) 732-389-3295x630
> UnixPros Inc. (home) 732-935-1590
> 10 Industrial Way East
> Eatontown, NJ 07724
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Every body have a right to say anything, But some stupid take it for granted
>
> ----Original Message-----
> From: Marc Saegesser [SMTP:[EMAIL PROTECTED]]
> Sent: Thursday, August 17, 2000 6:23 PM
> To: [EMAIL PROTECTED]
> Subject: Thread synchronization problem in init()
>
> I've encountered a very strange problem with thread synchronization
> in code
> executed by a servlet's init() method. I've included sample code
> below.
>
> Within my init() method I want to create an object that creates a
> new thread
> that will handle network communications. The main thread needs to
> block
> until the I/O thread notifies it that it has established a valid
> connection.
> I do this by creating an Object that the main thread waits on and
> the I/O
> thread notifies. The problem is that the I/O thread's run() method
> does not
> start executing until the main thread's wait() method times out. If
> I move
> this code from init() into doGet() it works fine.
>
> I've used Threadalyzer to take a look at what's happening and it
> appears
> that the java.lang.Thread.run is blocked waiting to acquire
> com.livesoftware.jrun.JRunServletLoader. This object is apparently
> held
> across the object.wait(). This prevents the run method from
> starting until
> the wait completes.
>
> The example code is in three files. WaitTest.java creates the I/O
> thread
> and waits for it to notify objWait. The I/O thread is simulated by
> calls to
> Thread.sleep(). AppTest.java is a simple servlet that creates an
> instance
> of WaitTest inside init() and calls its connect method. What I see
> in
> stderr.log is that the messages from inside the run method don't get
> displayed until after the objWait.wait() times out.
>
> AppTest2.java simply moves the WaitTest code from init() to doGet().
> When I
> run this I see the messages that I'm entering the wait, followed by
> the
> run() method starting and then the object gets notified.
>
> Am I doing something against the rules by creating threads inside
> the init()
> method? Is there any work around for this? Thanks.
>
> ----------- AppTest.java ------------------
> import java.io.*;
>
> import javax.servlet.*;
> import javax.servlet.http.*;
>
> /**
> *
> */
> public class AppTest extends HttpServlet
> {
> private WaitTest conn = null;
>
> public void init(ServletConfig config) throws
> ServletException
> {
> super.init(config);
>
> try{
> conn = new WaitTest();
> conn.connect();
> }catch(Exception e){
> System.err.println("AppTest.init: " +
> e.toString());
> }
> }
>
> public void doGet(HttpServletRequest req,
> HttpServletResponse res) throws
> ServletException, IOException
> {
> res.setContentType("text/html");
> PrintWriter out = res.getWriter();
>
> out.println("<html><body><h1>Blah</h1></body></html>");
> }
>
> public void destroy()
> {
> if(conn != null)
> conn.disconnect();
> }
> }
> --------------------------------------------
>
> ----------- AppTest2.java -----------------
> import java.io.*;
>
> import javax.servlet.*;
> import javax.servlet.http.*;
>
> public class AppTest2 extends HttpServlet
> {
> private WaitTest conn = null;
>
> public void init(ServletConfig config) throws
> ServletException
> {
> super.init(config);
>
> }
>
> public void doGet(HttpServletRequest req,
> HttpServletResponse res) throws
> ServletException, IOException
> {
> try{
> conn = new WaitTest();
> conn.connect();
> }catch(Exception e){
> System.err.println("AppTest.init: " +
> e.toString());
> }
>
> res.setContentType("text/html");
> PrintWriter out = res.getWriter();
>
> out.println("<html><body><h1>Blah</h1></body></html>");
> }
>
> public void destroy()
> {
> if(conn != null)
> conn.disconnect();
> }
> }
> --------------------------------------------
>
> ----------- WaitTest.java -----------------
> import java.io.*;
>
> public class WaitTest implements Runnable
> {
> private Thread thrdReader;
>
> private boolean bDisconnecting = false;
>
> private int nTimeout = 15000;
>
> private Object objWait = new Object();
>
> public void connect()
> {
> try{
> thrdReader = new Thread(this);
> System.err.println("WaitTest.connect:
> Starting reader thread.");
> thrdReader.start();
>
> try{
> synchronized(objWait){
>
> System.err.println("WaitTest.connect: Waiting for connection...");
> objWait.wait(nTimeout);
>
> System.err.println("WaitTest.connect: Wait returned.");
> }
> }catch(InterruptedException e){
>
> System.err.println("WaitTest.connect: " + e.toString());
> }
> }catch(Exception e){
> }
> }
>
> public void disconnect()
> {
> try{
> bDisconnecting = true;
>
> try{
> thrdReader.join(30000);
> }catch(InterruptedException e){
> }
> }catch(Exception e){
> System.err.println("WaitTest.disconnect:
> Caught exception. " +
> e.toString());
> }finally{
> bDisconnecting = false;
> }
> }
>
> public void run()
> {
> System.err.println("WaitTest.run: entered.");
>
> while(!bDisconnecting){
> try{
> Thread.currentThread().sleep(5000);
> synchronized(objWait){
> objWait.notifyAll();
> }
> }catch(InterruptedException e){
> }
> }
> System.err.println("WaitTest.run: leaving.");
> }
> }
> --------------------------------------------
>
>
> ----------------------------------------------------------------------------
> --
> Archives: http://www.egroups.com/group/jrun-interest/
> Unsubscribe:
> http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/jrun_talk
> or send a message to [EMAIL PROTECTED] with
> 'unsubscribe' in the body.
> ----------------------------------------------------------------------------
> --
> Archives: http://www.egroups.com/group/jrun-interest/
> Unsubscribe:
> http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/jrun_talk
> or send a message to [EMAIL PROTECTED] with 'unsubscribe'
> in the body.
>
> ------------------------------------------------------------------------------
> Archives: http://www.egroups.com/group/jrun-interest/
> Unsubscribe:
>http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/jrun_talk
> or send a message to [EMAIL PROTECTED] with 'unsubscribe' in the
>body.
>
Milt Epstein
Research Programmer
Software/Systems Development Group
Computing and Communications Services Office (CCSO)
University of Illinois at Urbana-Champaign (UIUC)
[EMAIL PROTECTED]
------------------------------------------------------------------------------
Archives: http://www.egroups.com/group/jrun-interest/
Unsubscribe: http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/jrun_talk
or send a message to [EMAIL PROTECTED] with 'unsubscribe' in the
body.