NIO socket 的簡單連線池

2021-08-31 12:03:48 字數 3335 閱讀 9544

在最近的專案中,需要寫乙個socket 與 底層伺服器通訊的模組。在設計中,請求物件被封裝 ***request,訊息返回被封裝為 ***response. 由於socket的程式設計開發經驗少,一開始我使用了短連線的方式,每個請求建立乙個socket通訊,由於每個socket只進行一次讀寫,這大大浪費了系統資源。

於是考慮使用長連線,系統公用乙個client socket 並對send 操作進行加鎖,結果在處理併發的時候,各種慢,各種等待。沒有辦法,考慮使用兩節池,預先建立多個 client socket 放入 連線池,需要傳送請求時從連線池獲取乙個socket,完成請求時放入連線池中。下面是乙個簡單的實現。

private  static string ip=globalnames.industryip;

private  static int port =integer.parseint(globalnames.industryport);

private static  int connection_pool_size = 10;

private static nioconnectionpool self = null;

private hashtablesocketpool = null; // 連線池

private boolean socketstatusarray = null; // 連線的狀態(true-被占用,false-空閒)

private static selector selector  = null;

private static inetsocketaddress server_address = null;

/*** 初始化連線池,最大tcp連線的數量為10

* * @throws ioexception

*/public static synchronized void init() throws exception

/*** 建立連線池

*/public synchronized static void buildconnectionpool() throws exception

for (int i = 0; i < connection_pool_size; i++)

}/**

* 從連線池中獲取乙個空閒的socket

* * @return 獲取的tcp連線

*/public static socketchannel getconnection() throws exception

}if (i < connection_pool_size) else

}/**

* 當獲得的socket不可用時,重新獲得乙個空閒的socket。

* * @param socket

*            不可用的socket

* @return 新得到的socket

* @throws exception

*/public static socketchannel rebuildconnection(socketchannel socket)

throws exception

socketchannel newsocket = null;

try

}} catch (exception e)

return newsocket;

}/**

* 將用完的socket放回池中,調整為空閒狀態。此時連線並沒有斷開。

* * @param socket

*            使用完的socket

* @throws exception

*/public static void releaseconnection(socketchannel socket) throws exception

for (int i = 0; i < connection_pool_size; i++) }}

/*** 斷開池中所有連線

* * @throws exception

*/public synchronized static void releaseallconnection() throws exception catch (exception e) }}

public static socketchannel allocatesocketchannel()}}

}catch(exception e)

return client;

}public static selector getselector()

使用連線池進行通訊:

/*緩衝區大小*/ 

private static int block = 8*4096;  

/*傳送資料緩衝區*/ 

private static bytebuffer sendbuffer = bytebuffer.allocate(block);  

/*接受資料緩衝區*/

private static bytebuffer protocalnum = bytebuffer.allocate(4);

private static bytebuffer functionnum = bytebuffer.allocate(4);

private static bytebuffer messagelen = bytebuffer.allocate(4);

private static bytebuffer receivebuffer = null;

private  socketchannel client = null;

private selector selector = null;

private boolean readable = true;

private boolean writable = true;

public niosocketbackup() throws exception

public string send(servicerequest request) throws exception else if (selectionkey.isreadable() && (readable) )

client.register(selector, selectionkey.op_write);  

receivetext = new string(receivebuffer.array(),"gbk");

flag = false;

readable = false;

break;

} }  

}nioconnectionpool.releaseconnection(client);

return receivetext.trim();

}  

構建簡單的socket連線池

前奏 這段時間,公司安排了乙個任務 構建乙個管理socket連線的連線池。一開始,選用vector來存放連線。由於這個容器不是併發安全的,於是,每個方法都加乙個synchronized來保持併發時的同步操作,併發效率很差,果斷放棄。空餘時間研究了下多執行緒的併發知識,決定用併發安全的阻塞佇列 lin...

jdbc 連線池的簡單使用

這裡使用的是c3p0的連線池,使用的jar包為c3p0 0.9.1.2.jar,使用的資料庫為oracle 下面直接上 連線池的設定 public class connpool catch exception e 通過連線池物件返回資料庫連線 return throws sqlexception p...

Proxool連線池的簡單配置

jdbc oracle thin 127.0.0.1 1521 ora oracle.jdbc.driver.oracledriver 90000 150 3 100 3 4 在web.xml裡新增如下 proxoolservletconfigurator org.logicalcobwebs.pr...