semaphore实现模拟数据库连接池

我们知道semaphore是一个共享型的同步机制,它的作用类似于一辆公交车有限定坐多少人,每次只有买票的人才能上车(acquire()获得许可),但是车的容量又是有限的,所以当达到一定容量的时候就后面的人就阻塞住上不来了,只能等车上有人下车(release()释放许可)。而这不正是数据库连接池的特性吗,像Druid,C3P0都是类似这样的机制。初始化固定的链接数量,当连接被消耗完毕时无法获取连接,当有SQL执行完毕连接被释放时,其他又可以进行连接。

Connect类

package niukewang;

import java.util.concurrent.TimeUnit;

public class Connect {

	private static int count = 1;
	private int id = count++;
	public Connect(){
		
		//假设打开一个连接需要耗费1秒
		try {
			TimeUnit.MICROSECONDS.sleep(1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	@Override
	public String toString(){
		
		return "#"+id+"#";
	}
}

DatabaseLink类

package niukewang;

import java.util.concurrent.Semaphore;

import org.omg.CORBA.PUBLIC_MEMBER;

public class DataBaselink {

	//连接池大小
	private int size;
	//当前数据库可用数
	private int available;
	//数据库连接集合
	private Connect[] connects;
	//连接状态
	private boolean[] connectFlag;
	//信号量对象
	private Semaphore semaphore;
	//初始化连接池大小
	public DataBaselink(int size){
		
		this.size = size;
		this.available = size;
		//信号量初始值为10,每成功进行一次acquire()操作,信号数减1,release()操作,信号数加1
		semaphore = new Semaphore(size,true);
		connects = new Connect[size];
		connectFlag = new boolean[size];
		initConnects();
	}
	//数据库初始化
	private void initConnects() {
		for (int i = 0; i < this.size; i++) {
			connects[i] = new Connect();
		}
	
	}
	//获得某个数据库连接,采用semaphore来控制
	public Connect openConnect() throws InterruptedException{
		//请求许可证,如何没有许可证,则一直阻塞
		semaphore.acquire();
		return getConnect();
	}
	//因为可能存在多个线程请求连接,所以应该设为synchronized
	private synchronized Connect getConnect() {
		
		for(int i=0;i<connectFlag.length;i++)
		{
			//找到没有被使用的连接
			if(connectFlag[i]== false)
			{
				//将该连接设为被连接了
				connectFlag[i] = true;
				available--;
				System.out.println("【"+Thread.currentThread().getName()+"】以获取连接      剩余连接数:" + available);
				//获得这个连接
				return connects[i];
			}
		}
		return null;
	}
	//释放连接
	public synchronized void releaseConnect(Connect connect)
	{
		for (int i = 0; i < connectFlag.length; i++) {
			if(connect == connects[i])
			{
				connectFlag[i] = false;
				available++;
				 System.out.println("【"+Thread.currentThread().getName()+"】已释放连接      剩余连接数:" + available);
				//信号量-1
				semaphore.release();
			}
		}
	}

	

}

TestThread类

package niukewang;

public class TestThread implements Runnable {

	private static DataBaselink pool = new DataBaselink(10);
	@Override
	public void run() {
		try {
			//打开一个连接
			Connect connect = pool.openConnect();
			Thread.sleep(100);
			pool.releaseConnect(connect);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	public static void main(String[] args) {
		for (int i = 0; i < 20; i++) {
			Thread thread = new Thread(new TestThread());
			thread.start();
		}
	}

}

运行结果
【Thread-1】以获取连接 剩余连接数:9
【Thread-5】以获取连接 剩余连接数:8
【Thread-4】以获取连接 剩余连接数:7
【Thread-3】以获取连接 剩余连接数:6
【Thread-2】以获取连接 剩余连接数:5
【Thread-0】以获取连接 剩余连接数:4
【Thread-8】以获取连接 剩余连接数:3
【Thread-9】以获取连接 剩余连接数:2
【Thread-6】以获取连接 剩余连接数:1
【Thread-7】以获取连接 剩余连接数:0
【Thread-7】已释放连接 剩余连接数:1
【Thread-1】已释放连接 剩余连接数:2
【Thread-5】已释放连接 剩余连接数:3
【Thread-4】已释放连接 剩余连接数:4
【Thread-3】已释放连接 剩余连接数:5
【Thread-2】已释放连接 剩余连接数:6
【Thread-0】已释放连接 剩余连接数:7
【Thread-8】已释放连接 剩余连接数:8
【Thread-19】以获取连接 剩余连接数:7
【Thread-6】已释放连接 剩余连接数:8
【Thread-16】以获取连接 剩余连接数:7
【Thread-9】已释放连接 剩余连接数:8
【Thread-15】以获取连接 剩余连接数:7
【Thread-17】以获取连接 剩余连接数:6
【Thread-14】以获取连接 剩余连接数:5
【Thread-12】以获取连接 剩余连接数:4
【Thread-13】以获取连接 剩余连接数:3
【Thread-11】以获取连接 剩余连接数:2
【Thread-10】以获取连接 剩余连接数:1
【Thread-18】以获取连接 剩余连接数:0
【Thread-15】已释放连接 剩余连接数:1
【Thread-17】已释放连接 剩余连接数:2
【Thread-16】已释放连接 剩余连接数:3
【Thread-19】已释放连接 剩余连接数:4
【Thread-13】已释放连接 剩余连接数:5
【Thread-18】已释放连接 剩余连接数:6
【Thread-11】已释放连接 剩余连接数:7
【Thread-14】已释放连接 剩余连接数:8
【Thread-12】已释放连接 剩余连接数:9
【Thread-10】已释放连接 剩余连接数:10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值