Site Search :
Standard Enterprise XML Methodology Pattern Setting Tunning Other
Article Contributors
GuestBook
Javapattern Maven
XSourceGen Dev
JetSpeed Test
JLook Image
jLook Family Site


SocketPool Implementation Source code Example
 
java.net.Socket 객체에 대한 Pooling 객체정의 및 구현샘플코드를 보도록 한다. ( 2003/03/10 ) 384
Written by specular - 전홍성
1 of 2
 

Pooling이란 것은 performance 개선과 reousrce의 효율적인 관리를 위해 이용되어지고, 사용예로는 ThreadPool, JDBC에서 ConnectionPool, ObjectPool등이 있다. 이번 article에서는 network programming을 할때 생성하는 Socket객체에 대한 pooling 소스를 소개 하겠습니다. Pooling을 구현 할때 중요 부분은 Pooling대상 객체를 얻기위해 Multi Thread가 접근하는 경우에 대한 Concurrency Issue를 해결해야 한다는 것이다.

Socket pooling객체는 다른 pooling 객체와 마찬가지로 server side component로 이용되어 지는데, . servlet/jsp web tier에서 특정 타 system과 socket 통신을 해야 한다거나, EJB component가 특정 타 system과 통신을 해야할 경우 이용할수 있죠. 위그림과 같이 특정 타 시스템의 Server Application에 connection을 연결하고 있는 Socket객체를 미리 생성해 pooling으로 관리하면, 그래서, 위 그림의 client는 servlet/jsp,ejb등의 server side component를 의미하는 것입니다. 다음은 SocketPool객체를 사용하는 client에대한 sequence입니다.
다음은 SocketPool에 대한 source 코드이다.

            
package specular.net;

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

/**
 *	SocketPool.java
 * 	Jeon HongSeong
 * 	2001.07.04
 */
public final class SocketPool 
{
	//Singleton
	private static SocketPool instance;
	
	private ArrayList free;
	private ArrayList used;
	private int count;
	
	//Configuration variable
	private static String HOST;
	private static int PORT;
	private static int MAX_COUNT;
	private static int INITIAL_COUNT;
	private static int TIMEOUT;
	private static boolean BLOCK;
	
	static {
		loadConf();		
		try {
			instance = new SocketPool();
		} catch(IOException e) {
			e.printStackTrace();	
		}
	}
	
	//Constructor
	private SocketPool() throws IOException {
		free = new ArrayList();
		used = new ArrayList();
		while(count<INITIAL_COUNT) {
			addSocket();
		}
	}
	
	public static SocketPool getInstance() 
		throws IOException 
	{
	if(instance==null) {
	  synchronized (SocketPool.class) {
	        if(instance==null) {
		instance = new SocketPool();	
	}	
	}	
	}
		
		return instance;
	} 
	
	//Loading the configuration from pool.properties file.
	private static void loadConf() {
		ResourceBundle rb = ResourceBundle.getBundle("pool") ;
		HOST = rb.getString("host");
		PORT = Integer.parseInt(rb.getString("port"));
		MAX_COUNT = Integer.parseInt(rb.getString("maxCons"));
		INITIAL_COUNT = Integer.parseInt(rb.getString("initialCons"));	
		String timeout = rb.getString("timeout");
		String block = rb.getString("block");
		if(block!=null) {
			BLOCK = Boolean.getBoolean(block);
			TIMEOUT = Integer.parseInt(timeout);
		}
		System.out.println("Socket Pooling Configuration ****************");
		System.out.println("Host : "+HOST);
		System.out.println("Port : "+PORT);
		System.out.println("Max_Count : "+MAX_COUNT);
		System.out.println("Min_Count : "+INITIAL_COUNT);
		System.out.println("BLOCK : "+BLOCK);
		System.out.println("TIMEOUT : "+TIMEOUT);
		System.out.println("---------------------------------------------");	
	}
	
	public Socket getSocket() 
		throws IOException 
	{
		return getSocket(BLOCK,TIMEOUT);	
	}
	
public synchronized Socket getSocket(boolean block, long timeout) 
throws IOException 
{
if(free.isEmpty()) {
	if(count<MAX_COUNT) {
		addSocket();	
	} else if(block) {
		try {
			synchronized(this) {
				wait(timeout);	
			}
		} catch(InterruptedException e) {
			e.printStackTrace();	
		}
		if(free.isEmpty()) {
			if(count<MAX_COUNT) {
			  addSocket();	
			} else {
			  throw new IOException("Timeout waiting "+
				for a socket to be released.");
			}	
		} 
	} else {
		throw new IOException("Maximum number "+
		of allowed Sockets reached");
	}			
}
Socket sck=null;
synchronized(used) {
	sck = (Socket)free.remove(free.size()-1);
	used.add(sck);
}
return sck;
}
	
public synchronized void release(Socket sck) 
	throws IOException 
{
	if(used.contains(sck)) {
		int idx = used.indexOf(sck);
		used.remove(idx);
		free.add(sck);	
	} else {
		throw new IOException("Socket " + sck +
				 " did not come from this SocketPool");
	}
	notify();		
}
	
public synchronized void closeAll() 
	throws IOException 
{
	for(int i=0;i<free.size();i++) {
		Socket sck = (Socket)free.remove(i);
		try {
			sck.close();
		} catch(IOException e) {
			System.out.println(e.toString());	
		}	
	}
	
	for(int i=0;i<used.size();i++) {
		used.remove(i);	
	}
}

private void addSocket() 
	throws IOException 
{
	Socket sck = new Socket(HOST,PORT);
	free.add(sck);
	count++;	
}
}

다음은 SocketPool 객체가 이용한는 Configuration 설정 파일이다. 이파일은 CLASSPATH경로에 있으면 된다.

            
host=127.0.0.1
port=8080
maxCons=100
initialCons=10
block=true
timeout=500 

Socket객체에 대한 resource를 효율 적으로 관리 하고자 한다면, Socket에 대한 사용이 적을경우 Socket객체를 close()시켜주는 Thread를 추가로 정의하면 되겠죠.

2001.07.04 written by Jeon HongSeong

 
 
1 2
References
 
Copyright ⓒ 2003 www.javapattern.info & www.jlook.com, an jLOOK co.,LTD