java socket连接池

一 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连接池一样,都是提高了服务器的性能 ,在服务器端维持了一个定量的资源,每次进行连接请求的时候 
      不同重复进行创建,一旦资源空闲直接获得,节省了频繁建立资源的时间,这两种连接池广泛存在于多线程的环境中。

你可能感兴趣的:(java)