在最近的專案中,需要寫乙個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...