Simulate a ConnectionDriver, for creating Connection
package tread.demo.threadpool; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.util.concurrent.TimeUnit; public class ConnectionDriver { static class ConnectionHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } } public static final Connection createConnection() { return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[]{Connection.class}, new ConnectionHandler()); } }
Thread pool implementation:
package tread.demo.threadpool; import java.sql.Connection; import java.util.LinkedList; public class ConnectionPool { private LinkedList<Connection> pool = new LinkedList<Connection>(); public ConnectionPool(int initialSize) { if (initialSize > 0) { for (int i = 0; i < initialSize; i++) { pool.addLast(ConnectionDriver.createConnection()); } } } public void releaseConnection(Connection connection) { if (connection != null) { synchronized (pool) { pool.addLast(connection);//将Connection还回给Pool pool.notifyAll();//通知等待的线程 } } } public Connection fetchConnection(long mills) throws Exception { synchronized (pool) { if (mills <= 0) { while (pool.isEmpty()) { pool.wait();//Band has been other release- "a Notify } return pool.removeFirst (); // get a Connection } the else { Long Future = System.currentTimeMillis () + Mills; Long Remaining = Mills; the while (pool.isEmpty () && Remaining> 0 ) { // based on the time to wait until a timeout. pool.wait (); Remaining = Future - System.currentTimeMillis (); } Connection Result = null ; IF (!pool.isEmpty()) { result = pool.removeFirst(); } return result; } } } }
Two:
- Object wait and notify
- Timeout waiting for time-based.
test:
package tread.demo.threadpool; import java.sql.Connection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; public class ConnectionPoolTest { static ConnectionPool pool = new ConnectionPool(10); static CountDownLatch start = new CountDownLatch(1); static CountDownLatch end; public static void main(String[] args) throws Exception { int threadCount = 1000; end = new CountDownLatch(threadCount); int count = 20; AtomicInteger got = new AtomicInteger(); AtomicInteger notGot = new AtomicInteger(); for (int i = 0; i < threadCount; i++) { Thread thread = new Thread(new ConnectionRunner(count, got, notGot), "ConnectionRunnerThread"); thread.start(); } start.countDown();//tart的CountDown为0,保证了所有线程同时执行。 end.await();//等待所有线程执行完毕, System.out.println("total invoke: " + (threadCount * count)); System.out.println("got connection: " + got); System.out.println("not got connection: " + notGot); } static class ConnectionRunner implements Runnable { int count; AtomicInteger got; AtomicInteger notGot; public ConnectionRunner(int count, AtomicInteger got, AtomicInteger notGot) { this.count = count; this.got = got; this.notGot = notGot; } public void run() { try { start.await();//等待start的CountDown为0. } catch (InterruptedException e) { e.printStackTrace(); } while (count > 0) { try { Connection connection = pool.fetchConnection(1);//超时时间 if (connection != null) { try { connection.createStatement(); } finally { pool.releaseConnection(connection); got.incrementAndGet(); } } else { notGot.incrementAndGet(); } } catch (Exception ex) { } finally { count--; } } end.countDown(); } } }
Continue Using the CatdownLatch
result:
total invoke: 20000 got connection: 11914 not got connection: 8086
If you adjust the timeout, adjusted to 100ms
The results are as follows (most of the time can get connection)
total invoke: 20000 got connection: 19050 not got connection: 950