java数据库连接池_方便自己学习
1、利用的等待 / 通知实现超时取连接
package cn.enjoyedu.ch1.pool;import java.sql.Connection;
import java.util.LinkedList;/**
类说明:连接池的实现
/
public class DBPool {</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">容器用于存放连接</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> LinkedList<Connection> pool = <span style="color: rgba(0, 0, 255, 1)">new</span> LinkedList<Connection><span style="color: rgba(0, 0, 0, 1)">(); </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">限制了连接池的大小</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> DBPool(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> initialSize) { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (initialSize > 0<span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < initialSize; i++<span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">模拟拿连接</span>
pool.addLast(SqlConnectImpl.fetchConnection());
}
}
}</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">释放连接,通知其他的等待连接的线程</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> releaseConnection(Connection connection) { </span><span style="color: rgba(0, 0, 255, 1)">if</span> (connection != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">synchronized</span><span style="color: rgba(0, 0, 0, 1)"> (pool){ pool.addLast(connection); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通知其他等待连接的线程</span>
pool.notifyAll();
}
}
}</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">获取</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在mills内无法获取到连接,将会返回null 1S</span> <span style="color: rgba(0, 0, 255, 1)">public</span> Connection fetchConnection(<span style="color: rgba(0, 0, 255, 1)">long</span> mills) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> InterruptedException { </span><span style="color: rgba(0, 0, 255, 1)">synchronized</span><span style="color: rgba(0, 0, 0, 1)"> (pool){ </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">永不超时</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(mills<=0<span style="color: rgba(0, 0, 0, 1)">){ </span><span style="color: rgba(0, 0, 255, 1)">while</span><span style="color: rgba(0, 0, 0, 1)">(pool.isEmpty()){ pool.wait(); } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> pool.removeFirst(); }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{ </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">超时时刻</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">long</span> future = System.currentTimeMillis()+<span style="color: rgba(0, 0, 0, 1)">mills; </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">等待时长</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">long</span> remaining =<span style="color: rgba(0, 0, 0, 1)"> mills; </span><span style="color: rgba(0, 0, 255, 1)">while</span>(pool.isEmpty()&&remaining>0<span style="color: rgba(0, 0, 0, 1)">){ pool.wait(remaining); </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">唤醒一次,重新计算等待时长</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)"> remaining </span>= future-<span style="color: rgba(0, 0, 0, 1)">System.currentTimeMillis(); } Connection connection </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">pool.isEmpty()){ connection </span>=<span style="color: rgba(0, 0, 0, 1)"> pool.removeFirst(); } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> connection; } } }
}
测试
package com.pool;import java.sql.Connection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;/**
类说明:测试并发 1000 次从池拿连接
/
public class DBPoolTest {
static DBPool pool = new DBPool(10);
// 控制器: 控制 main 线程将会等待所有 Woker 结束后才能继续执行
static CountDownLatch end;</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 线程数量</span> <span style="color: rgba(0, 0, 255, 1)">int</span> threadCount = 50<span style="color: rgba(0, 0, 0, 1)">; end </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CountDownLatch(threadCount); </span><span style="color: rgba(0, 0, 255, 1)">int</span> count = 20;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">每个线程的操作次数</span> AtomicInteger got = <span style="color: rgba(0, 0, 255, 1)">new</span> AtomicInteger();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">计数器:统计可以拿到连接的线程</span> AtomicInteger notGot = <span style="color: rgba(0, 0, 255, 1)">new</span> AtomicInteger();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">计数器:统计没有拿到连接的线程</span> <span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < threadCount; i++<span style="color: rgba(0, 0, 0, 1)">) { Thread thread </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Thread(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Worker(count, got, notGot), </span>"worker_"+<span style="color: rgba(0, 0, 0, 1)">i); thread.start(); } end.await();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> main线程在此处等待</span> System.out.println("总共尝试了: " + (threadCount *<span style="color: rgba(0, 0, 0, 1)"> count)); System.out.println(</span>"拿到连接的次数: " +<span style="color: rgba(0, 0, 0, 1)"> got); System.out.println(</span>"没能连接的次数: " +<span style="color: rgba(0, 0, 0, 1)"> notGot); } </span><span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span> Worker <span style="color: rgba(0, 0, 255, 1)">implements</span><span style="color: rgba(0, 0, 0, 1)"> Runnable { </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> count; AtomicInteger got; AtomicInteger notGot; </span><span style="color: rgba(0, 0, 255, 1)">public</span> Worker(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> count, AtomicInteger got, AtomicInteger notGot) { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.count =<span style="color: rgba(0, 0, 0, 1)"> count; </span><span style="color: rgba(0, 0, 255, 1)">this</span>.got =<span style="color: rgba(0, 0, 0, 1)"> got; </span><span style="color: rgba(0, 0, 255, 1)">this</span>.notGot =<span style="color: rgba(0, 0, 0, 1)"> notGot; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> run() { </span><span style="color: rgba(0, 0, 255, 1)">while</span> (count > 0<span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从线程池中获取连接,如果1000ms内无法获取到,将会返回null </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 分别统计连接获取的数量got和未获取到的数量notGot</span> Connection connection = pool.fetchConnection(1000<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (connection != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { connection.createStatement();</span>
connection.commit();
} finally {
pool.releaseConnection(connection);
got.incrementAndGet();
}
} else {
notGot.incrementAndGet();
System.out.println(Thread.currentThread().getName()
+"等待超时!");
}
} catch (Exception ex) {
} finally {
count--;
}
}
end.countDown();
}
}
}
结果
2、利用信号量实现数据库连接池:
注意可用连接 useful和无可用连接 useless都要管理起来,因为你不能保证每个人都会先拿连接再释放连接,这是信号量的一个坑
package com.semaphore;import java.sql.Connection;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;/**
类说明:Semaphore 实现数据库连接池
/
public class DBPoolSemaphore {</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> POOL_SIZE = 10<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">两个指示器,分别表示池子还有可用连接和已用连接</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span><span style="color: rgba(0, 0, 0, 1)"> Semaphore useful,useless; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">存放数据库连接的容器</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> LinkedList<Connection> pool = <span style="color: rgba(0, 0, 255, 1)">new</span> LinkedList<Connection><span style="color: rgba(0, 0, 0, 1)">(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">初始化池</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < POOL_SIZE; i++<span style="color: rgba(0, 0, 0, 1)">) { pool.addLast(SqlConnectImpl.fetchConnection()); } } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DBPoolSemaphore() { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.useful = <span style="color: rgba(0, 0, 255, 1)">new</span> Semaphore(10<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">this</span>.useless = <span style="color: rgba(0, 0, 255, 1)">new</span> Semaphore(0<span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">归还连接</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> returnConnect(Connection connection) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> InterruptedException { </span><span style="color: rgba(0, 0, 255, 1)">if</span>(connection!=<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { System.out.println(</span>"当前有"+useful.getQueueLength()+"个线程等待数据库连接!!" +"可用连接数:"+<span style="color: rgba(0, 0, 0, 1)">useful.availablePermits()); useless.acquire(); </span><span style="color: rgba(0, 0, 255, 1)">synchronized</span><span style="color: rgba(0, 0, 0, 1)"> (pool) { pool.addLast(connection); } useful.release(); } } </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">从池子拿连接</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> Connection takeConnect() <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> InterruptedException { useful.acquire(); Connection connection; </span><span style="color: rgba(0, 0, 255, 1)">synchronized</span><span style="color: rgba(0, 0, 0, 1)"> (pool) { connection </span>=<span style="color: rgba(0, 0, 0, 1)"> pool.removeFirst(); } useless.release(); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> connection; }
}
测试
package com.semaphore;import java.sql.Connection;
import java.util.Random;/**
类说明:测试数据库连接池
/
public class AppTest {</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> DBPoolSemaphore dbPool = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> DBPoolSemaphore(); </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span> BusiThread <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> Thread{ @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> run() { Random r </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Random();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">让每个线程持有连接的时间不一样</span> <span style="color: rgba(0, 0, 255, 1)">long</span> start =<span style="color: rgba(0, 0, 0, 1)"> System.currentTimeMillis(); </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { Connection connect </span>=<span style="color: rgba(0, 0, 0, 1)"> dbPool.takeConnect(); System.out.println(</span>"Thread_"+<span style="color: rgba(0, 0, 0, 1)">Thread.currentThread().getId() </span>+"_获取数据库连接共耗时【"+(System.currentTimeMillis()-start)+"】ms."<span style="color: rgba(0, 0, 0, 1)">); SleepTools.ms(</span>100+r.nextInt(100));<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">模拟业务操作,线程持有连接查询数据</span> System.out.println("查询数据完成,归还连接!"<span style="color: rgba(0, 0, 0, 1)">); dbPool.returnConnect(connect); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (InterruptedException e) { } } } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> main(String[] args) { </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < 50; i++<span style="color: rgba(0, 0, 0, 1)">) { Thread thread </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BusiThread(); thread.start(); } }
}
结果
Semaphore 信号量的一个坑,只管理可用连接,当开发者不按先取连接再释放连接的规则,就达不到流控的效果,
package com.semaphore;import java.sql.Connection;
import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Semaphore;/**
类说明:Semaphore 实现数据库连接池
/
public class DBPoolNoUseless {</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">int</span> POOL_SIZE = 10<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span><span style="color: rgba(0, 0, 0, 1)"> Semaphore useful; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">存放数据库连接的容器</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> LinkedList<Connection> pool = <span style="color: rgba(0, 0, 255, 1)">new</span> LinkedList<Connection><span style="color: rgba(0, 0, 0, 1)">(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">初始化池</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < POOL_SIZE; i++<span style="color: rgba(0, 0, 0, 1)">) { pool.addLast(SqlConnectImpl.fetchConnection()); } } </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DBPoolNoUseless() { </span><span style="color: rgba(0, 0, 255, 1)">this</span>.useful = <span style="color: rgba(0, 0, 255, 1)">new</span> Semaphore(10<span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">归还连接</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> returnConnect(Connection connection) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> InterruptedException { </span><span style="color: rgba(0, 0, 255, 1)">if</span>(connection!=<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { System.out.println(</span>"当前有"+useful.getQueueLength()+"个线程等待数据库连接!!" +"可用连接数:"+<span style="color: rgba(0, 0, 0, 1)">useful.availablePermits()); </span><span style="color: rgba(0, 0, 255, 1)">synchronized</span><span style="color: rgba(0, 0, 0, 1)"> (pool) { pool.addLast(connection); } useful.release(); } } </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">从池子拿连接</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> Connection takeConnect() <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> InterruptedException { useful.acquire(); Connection connection; </span><span style="color: rgba(0, 0, 255, 1)">synchronized</span><span style="color: rgba(0, 0, 0, 1)"> (pool) { connection </span>=<span style="color: rgba(0, 0, 0, 1)"> pool.removeFirst(); } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> connection; } </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> DBPoolNoUseless dbPoolNoUseless = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> DBPoolNoUseless(); </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span> BusiThread <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> Thread{ @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> run() { Random r </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Random();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">让每个线程持有连接的时间不一样</span> <span style="color: rgba(0, 0, 255, 1)">long</span> start =<span style="color: rgba(0, 0, 0, 1)"> System.currentTimeMillis(); </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { System.out.println(</span>"Thread_"+<span style="color: rgba(0, 0, 0, 1)">Thread.currentThread().getId() </span>+"_获取数据库连接共耗时【"+(System.currentTimeMillis()-start)+"】ms."<span style="color: rgba(0, 0, 0, 1)">); SleepTools.ms(</span>100+r.nextInt(100));<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">模拟业务操作,线程持有连接查询数据</span> System.out.println("查询数据完成,归还连接!"<span style="color: rgba(0, 0, 0, 1)">); dbPoolNoUseless.returnConnect(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SqlConnectImpl()); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (InterruptedException e) { } } } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> main(String[] args) { </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < 50; i++<span style="color: rgba(0, 0, 0, 1)">) { Thread thread </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BusiThread(); thread.start(); } }
}
模拟拿连接的类:
package cn.enjoyedu.ch1.pool;import cn.enjoyedu.tools.SleepTools;
import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;/**
类说明:
/
public class SqlConnectImpl implements Connection{</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">拿一个数据库连接</span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span><span style="color: rgba(0, 0, 0, 1)"> Connection fetchConnection(){ </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SqlConnectImpl(); } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">忽略其它 </span>
}