一 socket连接池
SocketServerPool 含有两个参数 listenPort , maxConnection 。分别表示监听端口和最大连接数。
函数setHandlers() 里面初始化了5个PoolConnectionHandler的线程,表示池中能同时最大处理5个连接。
二 线程池的助手类 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个链接。
四 总结
socket连接池 和 数据库jdbc连接池一样,都是提高了服务器的性能 ,在服务器端维持了一个定量的资源,每次进行连接请求的时候
不同重复进行创建,一旦资源空闲直接获得,节省了频繁建立资源的时间,这两种连接池广泛存在于多线程的环境中。
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() ;
}
}
* @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() ;
}
}
}
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连接池一样,都是提高了服务器的性能 ,在服务器端维持了一个定量的资源,每次进行连接请求的时候
不同重复进行创建,一旦资源空闲直接获得,节省了频繁建立资源的时间,这两种连接池广泛存在于多线程的环境中。