java数据连接池的并发探讨

来源:互联网 发布:js数组移除元素 编辑:程序博客网 时间:2024/05/16 10:45

现在比较流行的开源的连接有 dbcp ,c3p0 , proxool ,bonecp等其中proxool比较稳定一下,而且提供 监控,bonecp采用分区方式,通过动态均衡,实现连接的随机分配,而且运行速度也是最快的,但是bonecp采用的是LinkedBlockingQueue,这个列表的poll(time)存在泄露问题,当并发数量达到一定程度时,会出现poll超时现场.为了解决这个问题,可以采用一个数组来存储连接,然后对数据进行循环判断,当数组满了就阻塞所有的线程进行等待,直到释放数据库连接.

首先定义一个锁

protected final Lock wait_Lock = new ReentrantLock(); // 显式锁 
  // 条件对象维护了在此条件上的等待线程
  protected final Condition notFull = wait_Lock.newCondition(); // 非满的等待线程队列 

public Connection getConnection() throws SQLException
  {
    if (this.shutdownStarted)  return null;
   
    ConnectionWrapper con = getCon();//获得空闲的连接,因为子函数没有对异常进行捕获,如果有异常就抛出,不会阻塞线程
 

    if (con != null) {
      synchronized (con) {
        con.checkedout = true;
        con.lockTime = currTime;
      }      
      return con;
    }
   
    wait_Lock.lock();
      try {
        this.waitingForCon += 1;//增加一个等待线程
        while (true) {
          con = getCon();
          if (con != null) {          
            this.waitingForCon -= 1;//扣除一个等待线程
            synchronized (con) {
              con.checkedout = true;
              con.lockTime = currTime;
            }
            return con;
          }         
          System.out.println("没有空闲连接,进入等待!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
          log.println("没有空闲连接,进入等待!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
         // this.waitLock.wait();//程序执行到这个位置停止
          notFull.await(); // 缓存是满, 阻塞
        }
      }catch (InterruptedException ex){
        this.waitingForCon -= 1;//扣除一个等待线程
        //this.waitLock.notify();
        notFull.signal(); // 唤醒
        throw new SQLException("Interrupted while waiting for connection to become available.");
      }finally{
     wait_Lock.unlock();
      }
    }
  当释放连接的时候,如果有等等就唤醒线程.
  public void freeConnection()
  {
System.out.println("free sms connection!");
log.println("free sms connection!");
Iterator iterator;
     synchronized (this.threadMap) {
       List wrappers = getWrappersFromThreadMap(Thread.currentThread().getName());
       for (iterator = wrappers.iterator(); iterator.hasNext(); ) {
         ConnectionWrapper wrapper = (ConnectionWrapper)iterator.next();
         if (!wrapper.checkedout) {//不在使用
           iterator.remove();//移除
         }
       }
     }
     
    
     wait_Lock.lock();
     try{
     System.out.println("has "+waitingForCon+" waiting for connection!");
     log.println("has "+waitingForCon+" waiting for connection!");
      if (this.waitingForCon > 0) notFull.signal(); // 唤醒,缓存不空
     }finally{
    wait_Lock.unlock();
     } 
  }

通过上诉方法,能够很好的解决线程并发同步的问题,而且不存在内存泄露问题.

0 0
原创粉丝点击