已经有一段时间了,我再也无法访问代码了,但几年前我处理过类似的问题。该解决方案使用信号量来帮助实现并发性。创建一个可以全局共享的连接池类。当调用代码需要一个 unisession 时,如果可用,连接池会抓取一个,否则它会阻塞调用线程,直到有一个可用。当然,您不想像本例中那样硬编码计数或连接参数(其中大部分是从信号量 javadocs 复制的)。
import java.util.concurrent.Semaphore;
public class ConnectionPool
{
private static final int COUNT = 5;
private static final ConnectionPool INSTANCE = new ConnectionPool();
private final Semaphore available = new Semaphore(COUNT, true);
protected UniSession[] items = new UniSession[COUNT];
protected boolean[] used = new boolean[COUNT];
protected UniJava uniJava = new UniJava();
private ConnectionPool() {
for (int i = 0; i < COUNT; i++) {
items[i] = uniJava.openSession();
items[i].setHostName("server name");
items[i].setUserName("user name");
items[i].setPassword("password");
items[i].setAccountPath("account path");
items[i].connect();
}
}
public static ConnectionPool getInstance() {
return INSTANCE;
}
public UniSession borrow() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
}
public void release(UniSession session) {
if (markAsUnused(session))
available.release();
}
protected synchronized UniSession getNextAvailableItem() {
for (int i = 0; i < COUNT; ++i) {
if (!used[i]) {
used[i] = true;
return items[i];
}
}
return null;
}
protected synchronized boolean markAsUnused(Object item) {
for (int i = 0; i < COUNT; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
return true;
} else
return false;
}
}
return false;
}
}
然后在您的 API 代码中,当您需要一个 unisession 时,您会从池中借用一个,确保在完成后释放它。像这样的东西:
UniSession uniSession = null;
try {
uniSession = ConnectionPool.getInstance().borrow();
// do work
} finally {
ConnectionPool.getInstance().release(uniSession);
}
这使您的应用程序可以重用会话池,并且会话数永远不会超过您指定的计数。