我正在一个项目中使用不同模式的不同数据库中有两个表。因此,这意味着我有这两个表的两种不同的连接参数使用JDBC-插入时使用ConcurrentHashMap时线程安全问题
连接让我们假设以下是config.property文件 -
TABLES: table1 table2
#For Table1
table1.url: jdbc:mysql://localhost:3306/garden
table1.user: gardener
table1.password: shavel
table1.driver: jdbc-driver
#For Table2
table2.url: jdbc:mysql://otherhost:3306/forest
table2.user: forester
table2.password: axe
table2.driver: jdbc-driver
下面的方法将读取上述config.properties
文件,并作出每个表的对象为ReadTableConnectionInfo
。
private static void readPropertyFile() throws IOException {
prop.load(Read.class.getClassLoader().getResourceAsStream("config.properties"));
tableNames = Arrays.asList(prop.getProperty("TABLES").split(" "));
for (String arg : tableNames) {
ReadTableConnectionInfo ci = new ReadTableConnectionInfo();
String url = prop.getProperty(arg + ".url");
String user = prop.getProperty(arg + ".user");
String password = prop.getProperty(arg + ".password");
String driver = prop.getProperty(arg + ".driver");
ci.setUrl(url);
ci.setUser(user);
ci.setPassword(password);
ci.setDriver(driver);
tableList.put(arg, ci);
}
}
下面是ReadTableConnectionInfo class
,将持有的所有table connection info
特定表。
public class ReadTableConnectionInfo {
public String url;
public String user;
public String password;
public String driver;
public String percentage;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
}
现在我对线程的指定数量的创建ExecutorService
,并把该tableList
对象(即我创建通过阅读config.property file
)至ReadTask class
构造 -
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
service.submit(new ReadTask(tableList));
}
下面是我ReadTask
类,它实现Runnable interface
其中每个线程在做任何有意义的事情之前都会为起始中的每个表创建两个连接。
class ReadTask implements Runnable {
private Connection[] dbConnection = null;
private ConcurrentHashMap<ReadTableConnectionInfo, Connection> tableStatement = new ConcurrentHashMap<ReadTableConnectionInfo, Connection>();
public ReadTask(LinkedHashMap<String, XMPReadTableConnectionInfo> tableList) {
this.tableLists = tableList;
}
@Override
public void run() {
try {
int j = 0;
dbConnection = new Connection[tableList.size()];
//loop around the map values and make the connection list
for (ReadTableConnectionInfo ci : tableList.values()) {
dbConnection[j] = getDBConnection(ci.getUrl(), ci.getUser(), ci.getPassword(), ci.getDriver());
tableStatement.putIfAbsent(ci, dbConnection[j]);
j++;
}
//do other meaningful thing here
}
}
}
在我上面的try块,我对存储两个不同的数据库连接,使dbConnection array
。然后我有一个tableStatement
作为ConcurrentHashMap,其中我存储ReadTableConnectionInfo
对象与它的dbConnection
。例如Table1对象将在tableStatement
ConcurrentHashMap中具有Table1连接。
问题陈述: -
我想看看是否有任何潜在的thread safety issues
在这里我有我的tableStatement
的ConcurrentHashMap或这里的任何其他线程安全问题插入的方式运行的方法?
感谢您的建议。我稍微修改了我的'ReadTask类',只是为了更清楚。我不会在任何线程中修改'ReadTableConnectionInfo'类,只是我会做'getXxx调用'。你可以解释一下,你在第一行中提到的“线程之间不共享任务类”是什么意思?为什么我不需要'ConcurrentHashMap'?因为我需要将数据放在Map中吗?所以如果我使用HashMap,那么它可能有可能其他线程搞砸了吗? – AKIWEB 2013-02-26 03:14:24
@ Nevzz03 - 你正在向你的执行者提交一个新的'ReadTask'。在***当前***代码中,它们不在线程之间共享。我想如果你在主线程中同时访问它们,那么你需要更加担心同步问题,但是在你显示的代码中没有发生。 – Perception 2013-02-26 03:17:25
嗯。我有一部分,但我没有得到这一个 - '我想如果你在主线程中同时访问它们'。你能举个例子来说明一下,只是为了让自己更清楚。谢谢。 – AKIWEB 2013-02-26 03:20:05