在JAVA中使用多线程限制到oracle的连接数的多线程解决方案
我有一个线程,它在其中创建到oracle DB的连接,读取内容并写入csv文件。在每个线程中,DB中的内容被写入单独的csv文件。由于建立了n个到DB的连接,它会抛出一个异常,称为“ORA-00018:超出最大会话数”。请提供一个解决方案来停止它,但代码应该同时运行。下面是使用的代码
host s1 = new host(SYSNAME,SYSID);
s1.start();
class host extends Thread{
String SYSNAME,SYSID;
public host(String SYSNAME, String SYSID){
this.SYSNAME = SYSNAME;
this.SYSID = SYSID;
}
public void run(){
Connection conn;
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url, username, pwd);
String csv_file = "AverageValuesHost-" + SYSNAME + "-" + SYSID + "_Result.csv";
String host_query = null;
host_query = "My query";
ResultSet res_host = conn.createStatement().executeQuery(host_query);
CSVWriter wr = new CSVWriter(new FileWriter(csv_file), ',');
wr.writeAll(res_host, true);
wr.flush();
wr.close();
conn.close();
}
# 1 楼答案
您需要使用带有连接池的
DataSource
来创建连接(例如C3P0或HikariCP)。这允许您指定最大连接数,当连接不可用时,线程将被迫等待(直到超时),直到连接可用还要注意,创建更多线程并不总是完成更多工作的最佳方式。您还可以考虑使用具有固定数量的线程的^{} ,并将作业提交给该执行器服务。这样,一次运行的作业不会超过n,因此可以通过这种方式限制连接的数量
只需确保始终关闭连接(当出现异常时,当前代码无法正确执行此操作)。看看try-with-resources
# 2 楼答案
你能试试这样的吗。 1.创建自定义线程并在该自定义线程中初始化db连接 2.为fixedThreadPool()创建一个ThreadPoolExecutor,将连接数作为参数传递,并且此TPE应采用自定义线程工厂 3.创建一个可运行类,并访问 3.对于每个查询,创建一个runnable并提交给bq。 4.请勿在Runnable中使用任何等待/通知/或任何其他同步。一旦Runnable开始在线程内执行,它将完成Runnable的执行。它锁定了底层线程。[来自TPE代码]
这是一种非正统的方法,我从未见过Runnable从Thread(custom)类中取出一个对象来执行。但我没有发现任何问题,如果我错了,有人可以纠正我
我做了一个原型,请看一看,让我知道它是否符合你的目的。 好吧,这可以在很多方面得到改进,比如异常处理、拒绝处理等。但是首先,应该实现愉快的路径或目的
谢谢