我需要插入有两列的数据库 -
ID PrimaryKey String
ACCOUNT String
所以这意味着每个线程应该始终使用唯一的 id,我也需要ID
在Account
列中存储相同的 id。所以假设如果ID is 1
然后在数据库中它应该存储为
ID Account
1 SomeString+1
2 SomeString+2
3 SomeString+3
....
..
100 SomeString+100
我总是在帐户列中将该用户 ID 与该字符串连接起来。
下面是我的多线程代码,它将产生多个线程 - 每个线程每次都会获得一个新的唯一 ID,因为我正在使用AtomicInteger
它。它会将其插入并附ID
加到列ID column
ID
Account
但不知何故,在我下面的程序中,我在该数据库中看到的是 -
ID Account
1 String+2
2 String+1
3 String+3
这是不对的。应该是这样的——
ID Account
1 String+1
2 String+2
3 String+3
下面是代码
public static void main(String[] args) {
final int noOfThreads = 4;
final int noOfTasks = 10;
final AtomicInteger id = new AtomicInteger(1);
ExecutorService service = Executors.newFixedThreadPool(noOfThreads);
for (int i = 0; i < noOfTasks * noOfThreads; i++) {
service.submit(new Task(id));
}
}
class Task implements Runnable {
private final AtomicInteger id;
private volatile int userId;
public Task(AtomicInteger id) {
this.id = id;
}
@Override
public void run() {
dbConnection = getDBConnection();
preparedStatement = dbConnection.prepareStatement(Constants.INSERT_ORACLE_SQL);
userId = id.getAndIncrement();
preparedStatement.setString(1, String.valueOf(userId));
preparedStatement.setString(2, Constants.getaAccount(userId));
preparedStatement.executeUpdate();
}
}
下面是我Constants class
的不可变的。
public final class Constants {
public static String A_ACCOUNT;
public final static String INSERT_ORACLE_SQL = "INSERT INTO XMP_TEST"
+ "("
+ "ID, A_ACCOUNT) VALUES"
+ "(?, ?)";
public static String getaAccount(int userId) {
A_ACCOUNT = "{\"lv\":[{\"v\":{\"userId\":"+userId+"},\"cn\":1}]}";
return A_ACCOUNT;
}
}
谁能告诉我我在这里做错了什么?我相信这是因为线程安全问题而发生的。多个线程修改了userID
我猜的整数,这就是为什么它被错误地写入数据库的原因。
我该如何解决这个问题?