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.