0

I'm trying to use my own form of connection pooling to handle database connections but it seems to be blocking for some reason even though I used a thread, can someone help me point out my mistake please.

This is the servlet code with the thread class.

protected void processRequest(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    // PrintWriter out = response.getWriter();
    OutputStream ostream = response.getOutputStream();
    PrintStream out = new PrintStream(ostream, true, "UTF8");

    try {

        response.setContentType("text/html");
        String test = request.getParameter("test");
        System.out.println("Received text: " + test);

        if(test.equals("free"))
        {
            for (int i = 0; i < list.size(); i++) {
                dbcm.freeConnection(list.get(i));
            }
            list.clear();
        }else
        {
            GetConnThread gct = new GetConnThread(test, dbcm);
            gct.start();
        }

    } catch (Exception e) {
        e.printStackTrace();
        out.println("fail");
    } finally {
        out.close();
    }

}



private class GetConnThread extends Thread
{
    private String test;
    private DBConnectionManager dbcm;

    public GetConnThread(String test, DBConnectionManager dbcm)
    {
        this.test = test;
        this.dbcm = dbcm;
    }

    public void run()
    {
        try {
            Connection conn = dbcm.getConnection(test);
            list.add(conn);             
            System.out.println(conn);
            System.out.println("list size: " + list.size());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

This is the getConnection method in the DBConnectionManager

    public synchronized Connection getConnection(String test) throws CGFatalException {
        Connection con = null;
        boolean connectionIsValid = false;
        if (freeConnections.size() > 0) {

            con = (Connection) freeConnections.firstElement();
            freeConnections.removeElementAt(0);

            connectionIsValid = validateConnection(con);
            if (connectionIsValid == false) {
                con = getConnection(test);
            }
        } else if (maxConn == 0 || checkedOut < maxConn) {
            con = newConnection();
            connectionIsValid = validateConnection(con);
            if (connectionIsValid == false) {
                con = getConnection(test);
            }
        }else
        {
            System.out.println("No available connections for " + test + ", try again in 2 secs....");
            try {
                Thread.sleep(2000);
                con = getConnection(test);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (con != null && connectionIsValid == true) {
            checkedOut++;
        }
        System.out.println("checkedOut: " + checkedOut);
        System.out.println("maxConn: " + maxConn);
        return con;
    }

I set the max connections to 2 so after I call the servlet the 3rd time it goes to this line of code:

System.out.println("No available connections for " + test + ", try again in 2 secs....");

When I call it the 4th time, I'm expecting

System.out.println("No available connections for " + test + ", try again in 2 secs....");

to start as a seperate thread, but the 3rd call seems to be blocking it, the endless loop is expected because I was hoping to call "free" to clear the connections and everything goes back to normal.

3
  • I think you need to provide us with more information - probably a log file. You say the endless loop is expected, but you haven't shown us an endless loop. An the 3rd call seems to be blocking it, but there's no evidence for that, so we're having to rely on your guess work. Commented Feb 13, 2012 at 3:25
  • The "endless loop" is caused by the recursive call to try and get a "free" connection after the thread.sleep(2000). Commented Feb 13, 2012 at 3:27
  • 1
    Unless for pure hobby purposes, please do not homegrow connection pooling if you already don't understand how threading and concurrency work. Go pick an existing connection pool library. Every self-respected servletcontainer ships with builtin connection pooling facilities, Tomcat including. Make use of it. Really. Connection pooling is a too important artifact of a healthy webapplication which you don't want to homegrow with 0 understanding. Commented Feb 13, 2012 at 4:40

1 Answer 1

2

Your getConnection method is synchronized. Every other thread is going to block on that lock acquisition until the "third" request successfully gets a connection and proceeds.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes this is correct I just removed it and tested. If I remove the "synchonized" key word do you forsee and major problems I might face in terms of the counter for connections going haywire?
Looks like it would break without synchronization, yes. Instead of synchronizing the entire method use a java.util.concurrent.locks.Lock so that you can release the lock before going to sleep.
Sorry Affe 1 last question, where would you put the lock() and unlock() so that I can better understand how locks work as opposed to synchronized.
Ok I understood what you meant after mucking around, thanks a lot!
Sorry I missed your last followup there, glad it worked out for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.