java socket连接池

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

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

import java.io.*;
import java.net.*;


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 个之外的连接请求。

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

/**
 * 该类为助手类,用于管理连接池
 */
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个链接。

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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值