← Back to Advanced Java Course | Chapter 11: Advanced & Security | Lesson 17 of 19

Java Connection Pooling

What is Connection Pooling?

Opening and closing a database connection repeatedly is expensive -- it involves a network handshake, authentication, and session setup on the database side. Connection pooling solves this by keeping a pool of already-open connections ready to be reused, which dramatically improves throughput on high-traffic sites like cookiescursor.com that make many short-lived database calls.

Example: What is Connection Pooling?

java
public class Main {
	public static void main(String[] args) {
		// Opening a connection involves a handshake, auth, and session setup -- expensive to repeat
		System.out.println("Pooling reuses already-open connections instead of opening new ones every time");
	}
}

Structuring a Basic Pool

A basic connection pool manages a fixed collection of pre-opened connection objects, allocating that fixed number when the application starts and storing them inside a queue or list container that the rest of the application draws from as needed.

Example: Structuring a Basic Pool

java
import java.util.*;
public class Main {
	static class FakeConnection {}
	public static void main(String[] args) {
		Queue<FakeConnection> pool = new LinkedList<>();
		for (int i = 0; i < 5; i++) pool.add(new FakeConnection()); // fixed number, pre-opened at startup
		System.out.println("Pool size: " + pool.size());
	}
}

Acquiring and Releasing Connections

To use a pooled connection, application code borrows one from the pool rather than opening a fresh one. Once the database operation finishes, the code returns the connection back to the pool instead of actually closing it, so it stays available for the next caller.

Example: Acquiring and Releasing Connections

java
import java.util.*;
public class Main {
	static class FakeConnection {}
	public static void main(String[] args) {
		Queue<FakeConnection> pool = new LinkedList<>(List.of(new FakeConnection(), new FakeConnection()));
		FakeConnection borrowed = pool.poll(); // borrowed, not opened fresh
		System.out.println("Borrowed, remaining: " + pool.size());
		pool.offer(borrowed); // returned instead of closed
		System.out.println("Returned, remaining: " + pool.size());
	}
}

Thread-Safe Connection Pools

Since multiple threads can request connections from the same pool simultaneously, the pool's internal bookkeeping must be thread-safe -- typically via synchronized blocks or a concurrent data structure -- to prevent two threads from racing to grab or return the same connection incorrectly.

Example: Thread-Safe Connection Pools

java
import java.util.concurrent.*;
public class Main {
	static class FakeConnection {}
	public static void main(String[] args) {
		BlockingQueue<FakeConnection> pool = new LinkedBlockingQueue<>();
		pool.add(new FakeConnection()); // thread-safe container, no manual synchronization needed
		System.out.println("Thread-safe pool size: " + pool.size());
	}
}

Industry Standard Poolers

Writing a custom connection pool is a great learning exercise, but production applications almost always use a well-optimized, battle-tested library like HikariCP or Apache DBCP instead, since these offer advanced features like automatic idle-connection timeouts and leak detection that a hand-rolled pool would take significant effort to replicate safely.

Example: Industry Standard Poolers

java
public class Main {
	public static void main(String[] args) {
		// In production: HikariDataSource dataSource = new HikariDataSource(config);
		System.out.println("Production apps use HikariCP or Apache DBCP instead of a hand-rolled pool");
	}
}
Common Mistakes
  1. Forgetting to release connections back to the pool, causing the application to run out of connections and freeze.
  2. Setting the maximum pool size too high, which can overwhelm your database server resources.
  3. Attempting to modify database connection states directly instead of letting the pool manager handle them.
Chapter Summary
  • Connection pooling improves application performance by keeping a pool of active database connections ready to be reused.
  • Acquire connections from the pool on demand, and release them back to the pool inside finally blocks.
  • Always use synchronized blocks to protect the connection list from concurrent thread modifications.
Browser Support

Standard JDBC database connection pooling features are supported natively by all Java development kits.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.