1

I am new to using wait and notify. I have trouble in testing my code. Below is my implementation: (NOTE: I have not included all the implementation)

public class PoolImp {
  private Vector<Connection> connections; // For now maximum of 1 connection


  public synchronized Connection getconnection() {
       if(connections.size == 1() ) {
         this.wait();
     }
      return newConnection(); // also add to connections
  }

 public synchronized void removeconnection() {
       connections.size = 0;
       this.notify();
  }

}

Below is my test method: conn_1 gets the first connection. conn_2 goes into wait as only maximum of 1 connection is allowed.

I want to test this in such a way that when I call removeconnection, conn_2 gets notified and gets the released connection.

Testing : @Test

 public void testGetConnections() throws SQLException
{  
  PoolImpl cp = new PoolImpl();
  Connection conn_1 = null;
  Connection conn_2 = null;
  conn_1 = cp.getConnection();
  conn_2 = cp.getConnection();
  cp.removeConnection(conn_1);}
}   
user1180969
  • 95
  • 11
  • That is not what `wait()` and `notify()` are meant for. – Martijn Courteaux Jan 31 '12 at 18:08
  • 1
    What is `1()` ? wait() can return spuriously so you will want to use a while loop. – Peter Lawrey Jan 31 '12 at 18:12
  • FYI.There are a number of connection pool implementations out there. To name a couple- [dbcp](http://commons.apache.org/dbcp/) and [c3p0](http://sourceforge.net/projects/c3p0/) . No need to re-invent the wheel if the current ones get the job done for you. – CoolBeans Jan 31 '12 at 18:13
  • Ok !! thanks guys.. let me see what I can do... – user1180969 Jan 31 '12 at 18:14
  • @Peter: It was a typo.. supposed to be just if(connections.size == 1) – user1180969 Jan 31 '12 at 18:17
  • 2
    Using these methods correctly is very hard. And you failed. Use a higher-level abstraction like a blocking queue, which will do all this wait/notify dirty job for you. – JB Nizet Jan 31 '12 at 18:18
  • I want to emphasize what JB said. If you are new to `wait()` and `notify()`, I would suggest that you skip them for now, and first get familiar with the higher level utilities provided in the `java.util.concurrent` package, like [`BlockingQueue`.](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html) – erickson Jan 31 '12 at 18:27
  • Also, I'd be careful about using DBCP. It may have been fixed now, but it was so broken (all operations locked during resource allocation), for so long (a decade?), with no action or acknowledgement, that I wouldn't trust it. – erickson Jan 31 '12 at 18:29

3 Answers3

2

In order to test waiting and notifications, you need multiple threads. Otherwise, the waiting thread will block, and never get to the notifying code, because it is on the same thread.

P.S. Implementing connection pools is not an easy undertaking. I would not even bother, since you can use ready-made ones.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

Everyone right, you should take a ready-made class for your connection pool. But if you insist, I've fixed the code for you:

public class PoolImp {
  private Vector<Connection> connections; // For now maximum of 1 connection


  public synchronized Connection getconnection() {
       while(connections.isEmpty()) {
         this.wait();
     }
     return newConnection(); 
  }

 public synchronized void removeconnection(Connection c) {
       connections.add(c);
       this.notify();
  }

}

0

Replacing the if block with a while loop is an improvement but will not solve the real problem here. It will simply force another check on the size of the collection after a notify was issued, to ensure the validity of the claim made while issuing a notify().

As was pointed earlier, you need multiple client threads to simulate this. Your test thread is blocked when you call conn_2 = cp.getConnection();

Now, it never gets a chance to issue this call as it will wait indefinitely (unless it is interrupted) cp.removeConnection(conn_1);

Kailash
  • 785
  • 1
  • 8
  • 17