2つの列があるデータベースに挿入する必要があります-
ID PrimaryKey String
ACCOUNT String
つまり、各スレッドは常に一意のIDを使用する必要があり、同じものID
をAccount
列に格納する必要があります。したがってID is 1
、データベースに保存する必要がある場合は、
ID Account
1 SomeString+1
2 SomeString+2
3 SomeString+3
....
..
100 SomeString+100
そのuserIDを常にAccount列のその文字列と連結しています。
以下は、複数のスレッドを生成するマルチスレッドコードです-そして、各スレッドは、そのために使用しているたびに、新しい一意の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
整数を変更していると思います。そのため、データベースに誤って書き込まれています。
この問題を解決するにはどうすればよいですか?