模擬一個ConnectionDriver,用於創建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()); } }
線程池的實現:
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();//一直等帶release-》Notify } return pool.removeFirst();//得到一個connection } else { long future = System.currentTimeMillis() + mills; long remaining = mills; while (pool.isEmpty() && remaining > 0) {//基於時間進行等待,一直到超時。 pool.wait(); remaining = future - System.currentTimeMillis(); } Connection result = null; if (!pool.isEmpty()) { result = pool.removeFirst(); } return result; } } } }
兩點:
- 對象的wait和notify
- 基於超時時間的等待。
測試:
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(); } } }
繼續巧用了CatdownLatch
結果:
total invoke: 20000 got connection: 11914 not got connection: 8086
如果調整超時時間,調整為100ms
結果如下(大部分時候都能得到connection)
total invoke: 20000 got connection: 19050 not got connection: 950