我的团队必须进行一些更改并更新旧的 Web 应用程序。该应用程序有一个主线程和 5 到 15 个守护线程,用作工作线程,用于在数据库中检索和插入数据。
所有这些线程都具有这种设计(为方便起见,此处进行了简化):
public MyDaemon implements Runnable {
// initialization and some other stuffs
public void run() {
...
while(isEnabled) {
Engine.doTask1();
Engine.doTask2();
...
Thread.sleep(someTime);
}
}
}
Engine 类提供了一系列静态方法,用于处理 DataAccessor 类的其他方法,其中一些方法是静态的:
public Engine {
public static doTask1() {
ThisDataAccessor.retrieve(DataType data);
// some complicated operations
ThisDataAccessor.insertOrUpdate(DataType data);
}
public static doTask2() {
ThatDataAccessor da = new ThatDataAccessor();
da.retrieve(DataType data);
// etc.
}
...
}
DataAccessor 类通常使用包含在同步方法中的简单 JDBC 语句与 DB 交互(对于某些类是静态的)。DataSource 在服务器中配置。
public ThatDataAccessor {
public synchronized void retrieve(DataType data) {
Connection conn = DataSource.getConnection();
// JDBC stuff
conn.close();
}
...
}
问题是主线程需要连接到数据库,当这些守护线程工作时,我们很容易用完池中的可用连接,出现“等待连接超时”异常。此外,有时甚至那些守护线程也会得到相同的异常。
我们必须摆脱这个问题。
我们有一个配置了 20 个连接的连接池,不能再添加了,因为“20”是我们的生产环境标准。一些代码块需要同步,即使我们计划只在真正需要的地方移动“同步”关键字。但我不认为这会带来真正的不同。
我们在多线程编程方面没有经验,我们以前从未遇到过这个连接池问题,这就是为什么我要问:问题是由于这些线程的设计造成的吗?有没有我们没有注意到的缺陷?
我已经一一分析了线程类,只要它们没有并行运行,似乎就没有瓶颈可以证明那些“等待连接超时”的合理性。该应用程序使用 Oracle 11g 在 WebSphere 7 上运行。