一 socket连接池 
             
      SocketServerPool 含有两个参数 listenPort , maxConnection 。分别表示监听端口和最大连接数。

      函数setHandlers() 里面初始化了5个PoolConnectionHandler的线程,表示池中能同时最大处理5个连接。


    
/**
 * 
@author jake1036
 * 2010.7.16 20:05
 * socket连接池类
 
*/

package cn.bupt.net;
import java.io.*
import java.net.*;


/**
 * 
@author jake1036
 *
 
*/

public class SocketServerPool {

    
/*最大连接和监听端口*/
    
private int maxConnections ;
    
private int listenPort     ;
    
    
public SocketServerPool(int listenPort , int maxConnections){
        
this.listenPort = listenPort ;
        
this.maxConnections = maxConnections ;
        
    }
    
    
public void  acceptConnections(){        
        
try {
            ServerSocket serverSocket 
= new ServerSocket(listenPort , 5) ;
            Socket socket
= null ;
            
while(true)
            
{
                socket 
= serverSocket.accept() ;
                PoolConnectionHandler.processRequest(socket) ;
            }
    
        }
 catch (IOException e) {
            e.printStackTrace();
        }
        
        
    }

    
    
public void setHandlers()
    
{
       
for(int i = 0 ; i < this.maxConnections ; i++ )
       
{
           PoolConnectionHandler poolHandler 
= new PoolConnectionHandler() ;
           
new Thread(poolHandler , "handler" + i).start() ;
       }
    
    }

    
    
    
public static void main(String [] args)
    
{
        SocketServerPool pool 
= new SocketServerPool(8888 , 5) ;
        pool.setHandlers() ;
        pool.acceptConnections() ;    
    }

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
}



  二 线程池的助手类 PoolConnectionHandler

        在run方法中,如果当前的池pool为空那么 阻塞在wait()函数下 。一旦一个新的客户端连接,pool调用了notifyAll() 方法,
         pool被激活,然后调用handleConnection 方法。


       误区
                run() 方法中的 while(true) 死循环,是不可以去掉的。
               因为初始化了maxConnection 个 PoolConnectionHandler必须一直运行,否则删除掉循环的话,一旦处理完一次请求
              就会退出,无法响应maxConnection 个之外的连接请求。




   




        

package cn.bupt.net;

import java.io.*;
import java.net.*;
import java.util.LinkedList;
import java.util.List;

/**
 * 
@author jake1036
 * 该类为助手类,用于管理连接池
 
*/

public class PoolConnectionHandler implements Runnable{

    
protected Socket connection;
    
protected static List<Socket> pool = new LinkedList<Socket>();

    
/**
     * 
@param requestToHandler  
     * 每接收一个请求就在池中增加一个socket
     * 并通知所有等待的进程
     
*/

    
public static void processRequest(Socket requestToHandler) {
        
synchronized (pool) {
            pool.add(pool.size(), requestToHandler);
            pool.notifyAll();
        }


    }

    
    
public void handleConnection()
    
{    
        System.out.println(Thread.currentThread().getName() 
+ "handler" + connection) ;
        PrintWriter writer 
= null;   
        
try {
            writer 
= new PrintWriter(connection.getOutputStream()) ;
            writer.write(Thread.currentThread().getName() 
+ "handle me" + connection.getPort());
            writer.flush() ;                
        }
 catch (IOException e) {
            e.printStackTrace();
        }
finally{
            writer.close() ;
        }
    
    }

    
    
    
public void run()
    
{
        
        
/*
         * 此处while true循环是必须的
         * 否则该对象实例将会消失,达不到连接池的效果
         * 
         
*/

        
while(true)
        
{
            
synchronized(pool){
                
while(pool.isEmpty()){
                    
try {
                        pool.wait() ;
                    }
 catch (InterruptedException e) {
                        e.printStackTrace();
                        
return ;
                    }
            
                }

                connection 
= pool.remove(0) ;        
            }

            
            handleConnection() ;    
            
        }

    }

    
}




  三 客户端测试类 

        SocketClient 类继承了Runnable 接口,在run方法中,产生了100 次的链接,但是每次最多连接5个链接。




      
package cn.bupt.client;
import java.net.*
import java.io.*;

public class SocketClient implements Runnable{

     
public void run()
     
{
         
try {
            Socket socket 
= new Socket("192.168.1.101" , 8888) ;
            BufferedReader br 
= new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(br.readLine()) ;
            br.close() ;
            socket.close() ;            
        }
 catch (UnknownHostException e) {
            e.printStackTrace();
        }
 catch (IOException e) {
            e.printStackTrace();
        }

         
     }

    
     
public static void main(String [] args)
     
{
         
for(int i = 0 ; i < 100 ; i++ )
         
{
             
new Thread(new SocketClient()).start() ;
             
         }
 
     }

     
}





 四  总结 
      socket连接池 和 数据库jdbc连接池一样,都是提高了服务器的性能 ,在服务器端维持了一个定量的资源,每次进行连接请求的时候 
      不同重复进行创建,一旦资源空闲直接获得,节省了频繁建立资源的时间,这两种连接池广泛存在于多线程的环境中。



 
 












posted on 2010-07-16 22:37 buptduming 阅读(5303) 评论(9)  编辑  收藏
Comments
  • # re: java socket连接池
    巩宁
    Posted @ 2010-08-17 09:39
    没有考虑最大连接数,阻塞线程! 只考虑没有连接数,等待。  回复  更多评论   
  • # re: java socket连接池
    buptduming
    Posted @ 2010-08-18 13:49
    @巩宁
    当线程池没有可使用的连接的时候,新的客户端连接等待在wait()方法处。
    不知道您的疑问是什么?  回复  更多评论   
  • # re: java socket连接池
    yackl
    Posted @ 2012-01-10 21:01
    虽然是很老的文章,但是看了忍不住笑了
    这另类的线程池,原理就是客户端不断连接服务器,服务器将连接socket储存到队列中,最多启动5个线程去处理这个socket队列信息。。。
    优点:没看到
    缺点:
    1、没有减少socket建立的时间消耗,三次握手...
    2、如果客户端连接过多,一方面增加内存消耗,一方面服务器根本无法快速响应。如果超过服务器socket连接数限制,该爆的还是爆了

    实在是想不出来这种做法的意义。。。  回复  更多评论   
  • # re: java socket连接池
    leon.lv
    Posted @ 2012-06-06 10:07
    笑而无语  回复  更多评论   
  • # re: java socket连接池[未登录]
    java coder
    Posted @ 2012-11-19 10:44
    这个不能算连接池, 同意yackl说的观点,

    楼主说的“没有可以连接的时候,新的客户端连接等待在wait()方法处” 这句话是错的,你的pool.wait,是说,当没有新的客户端连接的时候,你的5个HandlerThread等待.  回复  更多评论   
  • # re: java socket连接池[未登录]
    aaa
    Posted @ 2013-06-26 11:36
    垃圾  回复  更多评论   
  • # re: java socket连接池
    songxin
    Posted @ 2015-05-06 10:06
    这个连接池没什么大的作用啊。
    服务器端是在接收到客户端的请求之后起一个线程处理的,
    你只能说你有5个线程等待处理socket请求。  回复  更多评论   
  • # re: java socket连接池
    songxin
    Posted @ 2015-05-06 10:08
    @yackl
    请问下,有没大概或者简单点的解决办法了?  回复  更多评论   
  • # re: java socket连接池
    songxin
    Posted @ 2015-05-06 10:13
    是不是可以在建立一个连接池,比如5个连接到服务器的连接,客户端在需要连接的时候,由服务器发给它一个可用的连接
      回复  更多评论   

只有注册用户登录后才能发表评论。


网站导航: