Semaphore是一种在多线程环境下使用的设施,该设施负责协调各个线程,以保证它们能够正确、合理的使用公共资源的设施,
也是操作系统中用于控制进程同步互斥的量。Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。
它相当于给线程规定一个量从而控制允许活动的线程数。
利用Semaphore设计一个链接池。
package com.business.thread.Semaphore;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
//数据库连接的平庸实现
public class SqlConnectionImpl implements Connection{
//重写Connection的方法,此处省略
//拿一个数据库连接
public static final Connection fetchConnection() {
// TODO Auto-generated method stub
return new SqlConnectionImpl();
}
}
package com.business.thread.Semaphore;
//一个使用Semaphore实现的数据库连接池
import java.sql.Connection;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;
/*Semaphore是一种在多线程环境下使用的设施,该设施负责协调各个线程,以保证它们能够正确、合理的使用公共资源的设施,
也是操作系统中用于控制进程同步互斥的量。Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。
它相当于给线程规定一个量从而控制允许活动的线程数。*/
public class DBPoolSemaphore {
//连接池的大小为10
private final static int POOL_SIZE = 10;
//存放连接的容器
private static LinkedList<Connection> pool = new LinkedList<Connection>();
//分别表示可用连接和已用连接
private final Semaphore useFul,useLess;
//初始化线程池
static {
for(int i=0;i<POOL_SIZE;i++) {
pool.addLast(SqlConnectionImpl.fetchConnection());
}
}
/*
* Semaphore主要构造方法
* Semaphore(int permits):构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。
* Semaphore(int permits,booleanfair):构造方法,当fair等于true时,创建具有给定许可数的计数信号量并设置为公平信号量。 void
* acquire():从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。 void acquire(int
* n):从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。 void
* release():释放一个许可,将其返回给信号量。就如同车开走返回一个车位。 void release(int n):释放n个许可。
* int availablePermits():当前可用的许可数。
*/
public DBPoolSemaphore(){
this.useFul = new Semaphore(POOL_SIZE);
this.useLess = new Semaphore(0);
}
//归还连接
public void returnConnection(Connection connection) throws InterruptedException {
if(connection!=null) {
System.out.println("当前有"+useFul.getQueueLength()+"个线程等待数据库连接!"+
"可用连接数: "+useFul.availablePermits());
useLess.acquire();
//对这个池进行加锁
synchronized (pool) {
pool.add(connection);
}
useFul.release();
}
}
//从池子拿连接
public Connection takeConnection() throws InterruptedException {
useFul.acquire();
Connection connection;
synchronized (pool) {
connection = pool.removeFirst();
}
useLess.release();
return connection;
}
}
package com.business.thread.Semaphore;
import java.sql.Connection;
import java.util.Random;
//测试数据库连接池
public class AppTest {
private static DBPoolSemaphore dbPool = new DBPoolSemaphore();
//拿数据库连接的线程
private static class busiThread extends Thread{
public void run() {
Random r = new Random();//让每个线程有个链接时间不一样
long start = System.currentTimeMillis();
Connection connection;
try {
connection = dbPool.takeConnection();
System.out.println("Thread_"+Thread.currentThread().getId()+
"_获取数据库连接共耗时【"+(System.currentTimeMillis()-start)+"】ms");
Thread.sleep(100+r.nextInt(100));
System.out.println("查询数据完成,归还连接");
dbPool.returnConnection(connection);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
for(int i = 0;i<50;i++) {
Thread thread = new busiThread();
thread.start();
}
}
}