我正在尝试在单个线程中为每个具有不同JDBC URL's
的数据库建立新连接。
在我的下面的代码段中,tableNames
是地图,其中包含表格的名称以及要连接到它们的属性。含义table1 will be in different database
和table2 will be in different database
tableNames
地图的示例示例 -
{table1={DRIVER=oracle.jdbc.driver.OracleDriver, PASSWORD=stage_cs_user, URL=jdbc_url, SUFFIX=xt1, SQL=sql, USER=user}, table2={DRIVER=driver_name, PASSWORD=pass, URL=jdbc_url2, SUFFIX=xt2, SQL=sql2, USER=user}}
以下是我的代码 -
class Task implements Runnable {
private Connection[] dbConnection = null;
private CallableStatement[] callableStatement = null;
private final ArrayList<Method> methods[] = null;
private final ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableLists;
public Task(ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableNames) {
this.tableLists = tableNames;
}
@Override
public void run() {
try {
int i=0;
for (Map<String, String> map : tableLists.values()) {
dbConnection[i] = getDBConnection(map.get("URL"), map.get("USER"), map.get("PASSWORD"), map.get("DRIVER"));
callableStatement[i] = dbConnection[i].prepareCall(map.get("SQL"));
methods[i] = getRequiredMethods(map.get("SUFFIX"));
i++;
}
}
}
}
在查看此代码时,它并不认为它是一个线程安全的代码。
我相信这里存在线程安全问题,因为多个线程将从tableLists Map
获取。有什么方法可以让这个线程安全吗?
所以我的问题是ConcurrentHashMap
从它检索数据时线程安全吗?有没有什么方法可以让这个线程在这里保持安全并稍微提高一点?
更新了代码并提供了更多详细信息: -
class Task implements Runnable {
private Connection[] dbConnection = null;
private CallableStatement[] callableStatement = null;
private final ArrayList<Method> methods[] = null;
private final ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableLists;
public Task(ConcurrentHashMap<String, ConcurrentHashMap<String, String>> tableNames) {
this.tableLists = tableNames;
}
@Override
public void run() {
try {
int j=0;
dbConnection = new Connection[tableLists.size()];
callableStatement = new CallableStatement[tableLists.size()];
methods = new ArrayList[tableLists.size()];
for (Map<String, String> map : tableLists.values()) {
dbConnection[j] = getDBConnection(map.get("URL"), map.get("USER"), map.get("PASSWORD"), map.get("DRIVER"));
callableStatement[j] = dbConnection[j].prepareCall(map.get("SQL"));
methods[j] = getRequiredMethods(map.get("SUFFIX"));
j++;
}
for (int userId = id; userId < id + noOfTasks; userId++) {
for (int spot = 0; spot < dbConnection.length; spot++) {
callableStatement[spot].setString(1, String.valueOf(userId));
for (int i = 0; i < methods.length; i++) {
methods[spot].get(i).invoke(null, callableStatement[spot], userId);
}
long start = System.nanoTime();
callableStatement[spot].executeUpdate(); // flush the records.
long end = System.nanoTime() - start;
final AtomicLong before = histogram.putIfAbsent(end / 1000000, new AtomicLong(1L));
if (before != null) {
before.incrementAndGet();
}
}
}
} finally {
closeConnection(callableStatement, dbConnection);
}
}
}