Java并发编程--Semaphore及模拟实现一个连接池

什么是Semaphore

Semaphore(信号量)是java.util.concurrent包下一个重要的工具类。Semaphore类似synchronized的加强版,作用是控制线程的并发数量。而就这一点而言,synchronized关键字是实现不了的。

Semaphore内部也是基于AQS实现的,将AQS下的state用作保存允许的流量数,访问特定资源前,必须使用acquire方法获得许可,如果许可数量为0,该线程则一直阻塞,直到有可用许可。这一点与共享锁的实现类似。

Semaphore和ReentrantLock类似,获取许可有公平策略和非公平许可策略,默认情况下使用非公平策略。当初始值为1时,可以用作互斥锁,并具备不可重入的加锁语义。

 

Semaphore常用的一些接口

  • Semaphore(permits):构造方法,permits 为初始化许可证数量的构造函数,默认为非公平锁
  • Semaphore(permits,fair)构造方法,初始化许可证数量和是否公平模式的构造函数
  • acquire():当前线程尝试去阻塞的获取1个许可证,如果获取不到则阻塞当前线程
  • tryAcquire():线程尝试去获取1个许可证,如果获取不到返回false继续执行,不会阻塞当前线程
  • tryAcquire(timeout,TimeUnit):线程尝试去获取1个许可证,如果获取不到则阻塞等待一个超时时间,超时后返回false继续执行
  • release():当前线程释放1个可用的许可证
  • availablePermits():当前可用的许可证数量
  • hasQueuedThreads():判断当前Semaphore对象上是否存在正在等待许可证的线程
  • getQueueLength():获取当前Semaphore对象上是正在等待许可证的线程数量

 

模拟实现数据库连接池

通过Semaphore模拟实现一个数据库的连接池

public class DBPoolSemaphore {

    private final static int POOL_SIZE = 10;
    private final Semaphore useful,useless;//useful表示可用的数据库连接,useless表示已用的数据库连接

    public DBPoolSemaphore() {
        this.useful = new Semaphore(POOL_SIZE);
        this.useless = new Semaphore(0);
    }

    //存放数据库连接的容器
    private static LinkedList<Connection> pool = new LinkedList<Connection>();
    //初始化池
    static {
        for (int i = 0; i < POOL_SIZE; i++) {
            pool.addLast(SqlConnectImpl.fetchConnection());
        }
    }

    /*归还连接*/
    public void returnConnect(Connection connection) throws InterruptedException {
        if(connection!=null) {
            System.out.println("当前有"+useful.getQueueLength()+"个线程等待数据库连接!!"
                    +"可用连接数:"+useful.availablePermits());
            useless.acquire();
            synchronized (pool) {
                pool.addLast(connection);
            }
            useful.release();
        }
    }

    /*从池子拿连接*/
    public Connection takeConnect() throws InterruptedException {
        useful.acquire();   // 申请信号量(useful - 1),如果取不到则进入等待队列,阻塞线程
        Connection conn;
        synchronized (pool) {
            conn = pool.removeFirst();
        }
        useless.release();  // 释放信号量(useless + 1)
        return conn;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值