构建简单的socket连接池

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

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

  1 public class SocketConnectionPool {
  2 
  3     private ConnectionPoolConfig poolConfig; // 连接池配置
  4     private LinkedBlockingQueue freeConnections; // 空闲池连接
  8     
  9     public ConnectionPoolConfig getPoolConfig() {
 10         return poolConfig;
 11     } 21     public LinkedBlockingQueue 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(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){
 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连接池,完全满足了应用的需求,哈哈~~~

 

 

转载于:https://www.cnblogs.com/mihu/p/3208956.html

你可能感兴趣的:(构建简单的socket连接池)