• 构建简单的socket连接池


    一开始,选用Vector<E>来存放连接。由于这个容器不是并发安全的,于是,每个方法都加一个synchronized来保持并发时的同步操作,并发效率很差,果断放弃。空余时间研究了下多线程的并发知识,决定用并发安全的阻塞队列(LinkedBlockingQueue<E>),这个容器可以自动维护容量的大小,就免去了再起一个线程去维护线程池的大小。为了保证每个连接是可用的,为线程池启动了一个守护线程去定时发送心跳。

    程序如下,欢迎高手们指点缺陷:

      1 public class SocketConnectionPool {
      2 
      3     private ConnectionPoolConfig poolConfig; // 连接池配置
      4     private LinkedBlockingQueue<SocketConnection> freeConnections; // 空闲池连接
      8     
      9     public ConnectionPoolConfig getPoolConfig() {
     10         return poolConfig;
     11     } 21     public LinkedBlockingQueue<SocketConnection> getFreeConnections() {
     22         return freeConnections;
     23     }
     24     /**
     25      * 功能描述:连接池构造方法
     26      * 
     27      * @author mihu
     28      * @version mihu
     29      * @param config
     30      * @throws UnknownHostException
     31      * @throws IOException
     32      */
     33     public SocketConnectionPool(ConnectionPoolConfig config){
     34         try {
     35             if(config == null){
     36                 log.error("func[init] ConnectionPoolConfig is null ......");
     37                 return;
     38             }
     39             
     40             this.poolConfig = config;
     41             this.freeConnections = new LinkedBlockingQueue<SocketConnection>(config.getMaxConn());  //构造指定大小的阻塞队列
     42             
     43             init();
     44             
     45         } catch (UnknownHostException e) {
     46             e.printStackTrace();
     47         } catch (ConnectException e){
     48             e.printStackTrace();
     49         } catch (SocketTimeoutException e){
     50             e.printStackTrace();
     51         } catch (IOException e) {
     52             e.printStackTrace();
     53         } catch (Exception e) {
     54             e.printStackTrace();
     55         } finally{
     56             
     57             //心跳检测守护线程
     58             if(config != null){
     59                 ACheckThread aCheckThread = new ACheckThread(this);
     60                 aCheckThread.setDaemon(true);
     61                 aCheckThread.start();
     62             }
     63         }
     64     }
     65     
     66     /**
     67      * 功能描述:初始化连接池
     68      * 
     69      * @return
     70      * @throws UnknownHostException
     71      * @throws IOException 
     72      * @author mihu
     73      * @version mihu
     74      * @throws InterruptedException 
     75      * @since 2013-7-2
     76      *
     77      */
     78     public void init() throws UnknownHostException, IOException,SocketTimeoutException,ConnectException, InterruptedException{
     79         
     80         for(int i=0; i<poolConfig.getMinConn(); i++){
     81             SocketConnection client = new SocketConnection(poolConfig.getHost(), poolConfig.getPort());
     82             freeConnections.offer(client);
     83         }
     84         
     85     }
     86     
     87     /**
     88      * 功能描述:新建连接
     89      * 
     90      * @param totalConnSize
     91      * @throws UnknownHostException
     92      * @throws IOException 
     93      * @author mihu
     94      * @version mihu
     95      * @since 2013-7-2
     96      *
     97      */
     98     public SocketConnection newConnection() throws UnknownHostException, IOException{
     99         SocketConnection client = new SocketConnection(this.poolConfig.getHost(), this.poolConfig.getPort());
    100         
    101         return client;
    102     }
    103     
    104     /**
    105      * 功能描述:获取连接
    106      * 
    107      * @return SocketConnection连接
    108      * @throws UnknownHostException
    109      * @throws IOException 
    110      * @author mihu
    111      * @version mihu
    112      * @throws InterruptedException 
    113      * @since 2013-7-2
    114      *
    115      */
    116     public SocketConnection getConnection() throws UnknownHostException, IOException, InterruptedException{
    117         if(freeConnections.size()==0){
    118             synchronized (freeConnections) {
    119                 int freeConnCount = freeConnections.size();
    120                 if(freeConnCount == 0 && freeConnCount < this.poolConfig.getMaxConn()){
    121                     SocketConnection client = newConnection();
    122                     return client;
    123                 }
    124             }
    125         }
    126         
    127         SocketConnection client = freeConnections.poll(2000,TimeUnit.MILLISECONDS);
    128         
    129         return client;
    130     }
    131     
    132     
    133     /**
    134      * 功能描述:将连接还回连接池
    135      * 
    136      * @param client
    137      * @throws IOException 
    138      * @author mihu
    139      * @version mihu
    140      * @throws InterruptedException 
    141      * @since 2013-7-2
    142      *
    143      */
    144     public void freeConnection(SocketConnection client) throws IOException, InterruptedException{
    145         if(null != client && !client.isClosed()){
    146             freeConnections.offer(client);
    147         }
    148     }
    149     
    150 }

     以上连接池的代码已经被废弃了,多线程下问题多多。

     某天在网上看到数据库连接池的开源代码boneCP,据说是当前最高效的数据库连接池。于是下载了它的源码学习了一番,发现它的代码简洁,可阅读性强,没有过多的使用锁机制来避免临界竞争,这一点和c3p0很不同。

     最后根据boneCP的思维重构了自己的socket连接池,完全满足了应用的需求,哈哈~~~

  • 相关阅读:
    「USACO15FEB」Censoring (Silver) 审查(银) 解题报告
    「Luogu P2278」[HNOI2003]操作系统 解题报告
    「Luogu P1210」回文检测 解题报告
    「Luogu P4987」回文项链 解题报告
    「Luogu P1435」回文字串 解题报告
    「Luogu P3931」SAC E#1
    「UVA1328」Period 解题报告
    「Poj1845」Sumdiv 解题报告
    测试
    nginx、Apache、Lighttpd启用HSTS
  • 原文地址:https://www.cnblogs.com/mihu/p/3208956.html
Copyright © 2020-2023  润新知