package com.xiangxue.ch1.pool; import java.sql.*; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; import com.xiangxue.tools.SleepTools; /** *类说明:实现了数据库连接的实现 */ public class SqlConnectImpl implements Connection{ /*拿一个数据库连接*/ public static final Connection fetchConnection(){ return new SqlConnectImpl(); } @Override public boolean isWrapperFor(Class<?> arg0) throws SQLException { // TODO Auto-generated method stub return false; } @Override public <T> T unwrap(Class<T> arg0) throws SQLException { // TODO Auto-generated method stub return null; } @Override public void abort(Executor arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void clearWarnings() throws SQLException { // TODO Auto-generated method stub } @Override public void close() throws SQLException { // TODO Auto-generated method stub } @Override public void commit() throws SQLException { SleepTools.ms(70); } @Override public Array createArrayOf(String arg0, Object[] arg1) throws SQLException { // TODO Auto-generated method stub return null; } @Override public Blob createBlob() throws SQLException { // TODO Auto-generated method stub return null; } @Override public Clob createClob() throws SQLException { // TODO Auto-generated method stub return null; } @Override public NClob createNClob() throws SQLException { // TODO Auto-generated method stub return null; } @Override public SQLXML createSQLXML() throws SQLException { // TODO Auto-generated method stub return null; } @Override public Statement createStatement() throws SQLException { SleepTools.ms(1); return null; } @Override public Statement createStatement(int arg0, int arg1) throws SQLException { // TODO Auto-generated method stub return null; } @Override public Statement createStatement(int arg0, int arg1, int arg2) throws SQLException { // TODO Auto-generated method stub return null; } @Override public Struct createStruct(String arg0, Object[] arg1) throws SQLException { // TODO Auto-generated method stub return null; } @Override public boolean getAutoCommit() throws SQLException { // TODO Auto-generated method stub return false; } @Override public String getCatalog() throws SQLException { // TODO Auto-generated method stub return null; } @Override public Properties getClientInfo() throws SQLException { // TODO Auto-generated method stub return null; } @Override public String getClientInfo(String arg0) throws SQLException { // TODO Auto-generated method stub return null; } @Override public int getHoldability() throws SQLException { // TODO Auto-generated method stub return 0; } @Override public DatabaseMetaData getMetaData() throws SQLException { // TODO Auto-generated method stub return null; } @Override public int getNetworkTimeout() throws SQLException { // TODO Auto-generated method stub return 0; } @Override public String getSchema() throws SQLException { // TODO Auto-generated method stub return null; } @Override public int getTransactionIsolation() throws SQLException { // TODO Auto-generated method stub return 0; } @Override public Map<String, Class<?>> getTypeMap() throws SQLException { // TODO Auto-generated method stub return null; } @Override public SQLWarning getWarnings() throws SQLException { // TODO Auto-generated method stub return null; } @Override public boolean isClosed() throws SQLException { // TODO Auto-generated method stub return false; } @Override public boolean isReadOnly() throws SQLException { // TODO Auto-generated method stub return false; } @Override public boolean isValid(int arg0) throws SQLException { // TODO Auto-generated method stub return false; } @Override public String nativeSQL(String arg0) throws SQLException { // TODO Auto-generated method stub return null; } @Override public CallableStatement prepareCall(String arg0) throws SQLException { // TODO Auto-generated method stub return null; } @Override public CallableStatement prepareCall(String arg0, int arg1, int arg2) throws SQLException { // TODO Auto-generated method stub return null; } @Override public CallableStatement prepareCall(String arg0, int arg1, int arg2, int arg3) throws SQLException { // TODO Auto-generated method stub return null; } @Override public PreparedStatement prepareStatement(String arg0) throws SQLException { // TODO Auto-generated method stub return null; } @Override public PreparedStatement prepareStatement(String arg0, int arg1) throws SQLException { // TODO Auto-generated method stub return null; } @Override public PreparedStatement prepareStatement(String arg0, int[] arg1) throws SQLException { // TODO Auto-generated method stub return null; } @Override public PreparedStatement prepareStatement(String arg0, String[] arg1) throws SQLException { // TODO Auto-generated method stub return null; } @Override public PreparedStatement prepareStatement(String arg0, int arg1, int arg2) throws SQLException { // TODO Auto-generated method stub return null; } @Override public PreparedStatement prepareStatement(String arg0, int arg1, int arg2, int arg3) throws SQLException { // TODO Auto-generated method stub return null; } @Override public void releaseSavepoint(Savepoint arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void rollback() throws SQLException { // TODO Auto-generated method stub } @Override public void rollback(Savepoint arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void setAutoCommit(boolean arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void setCatalog(String arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void setClientInfo(Properties arg0) throws SQLClientInfoException { // TODO Auto-generated method stub } @Override public void setClientInfo(String arg0, String arg1) throws SQLClientInfoException { // TODO Auto-generated method stub } @Override public void setHoldability(int arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void setNetworkTimeout(Executor arg0, int arg1) throws SQLException { // TODO Auto-generated method stub } @Override public void setReadOnly(boolean arg0) throws SQLException { // TODO Auto-generated method stub } @Override public Savepoint setSavepoint() throws SQLException { // TODO Auto-generated method stub return null; } @Override public Savepoint setSavepoint(String arg0) throws SQLException { // TODO Auto-generated method stub return null; } @Override public void setSchema(String arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void setTransactionIsolation(int arg0) throws SQLException { // TODO Auto-generated method stub } @Override public void setTypeMap(Map<String, Class<?>> arg0) throws SQLException { // TODO Auto-generated method stub } }
package com.xiangxue.ch1.pool; import java.sql.Connection; import java.util.LinkedList; /** *类说明:实现一个数据库的连接池 */ public class DBPool { //数据库池的容器 private static LinkedList<Connection> pool = new LinkedList<>(); public DBPool(int initalSize) { if(initalSize>0) { for(int i=0;i<initalSize;i++) { pool.addLast(SqlConnectImpl.fetchConnection()); } } } //在mills时间内还拿不到数据库连接,返回一个null public Connection fetchConn(long mills) throws InterruptedException { synchronized (pool) { if (mills<0) { while(pool.isEmpty()) { pool.wait(); } return pool.removeFirst(); }else { long overtime = System.currentTimeMillis()+mills; long remain = mills; while(pool.isEmpty()&&remain>0) { pool.wait(remain); remain = overtime - System.currentTimeMillis(); } Connection result = null; if(!pool.isEmpty()) { result = pool.removeFirst(); } return result; } } } //放回数据库连接 public void releaseConn(Connection conn) { if(conn!=null) { synchronized (pool) { pool.addLast(conn); pool.notifyAll(); } } } }
package com.xiangxue.ch1.pool; import java.sql.Connection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; /** *类说明: */ public class DBPoolTest { static DBPool pool = new DBPool(10); // 控制器:控制main线程将会等待所有Woker结束后才能继续执行 static CountDownLatch end; public static void main(String[] args) throws Exception { // 线程数量 int threadCount = 50; 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 Worker(count, got, notGot), "worker_"+i); thread.start(); } end.await();// main线程在此处等待 System.out.println("总共尝试了: " + (threadCount * count)); System.out.println("拿到连接的次数: " + got); System.out.println("没能连接的次数: " + notGot); } static class Worker implements Runnable { int count; AtomicInteger got; AtomicInteger notGot; public Worker(int count, AtomicInteger got, AtomicInteger notGot) { this.count = count; this.got = got; this.notGot = notGot; } public void run() { while (count > 0) { try { // 从线程池中获取连接,如果1000ms内无法获取到,将会返回null // 分别统计连接获取的数量got和未获取到的数量notGot Connection connection = pool.fetchConn(-9); if (connection != null) { try { connection.createStatement(); connection.commit(); } finally { pool.releaseConn(connection); got.incrementAndGet(); } } else { notGot.incrementAndGet(); System.out.println(Thread.currentThread().getName() +"等待超时!"); } } catch (Exception ex) { } finally { count--; } } end.countDown(); } } }