Java でマルチスレッドが必要なプログラムがあります。このMain
関数は、MySQL DB に対してクエリを実行して値を選択し、一度に 1 つずつ各スレッドにname
送信します。name
各スレッドは、 this に依存する操作を行いますname
。run
関数はメソッドを呼び出します。たとえば、このmethod1
メソッドClass1
はいくつかの操作を実行し、table2 の DB に値をmethod2
挿入します。また、table1 で操作と挿入を行う別のメソッドを呼び出します。
DB には table1 と table2 が 1 対多で含まれています。しかし、私はまだテーブルを接続していません。それらは今まで分離されています。table2
ただし、特定のレコードが table1 のどのレコードにtable2
属しているかを反映する列があります。table2 の DB は正しいが、table1 は間違っている (例: 最初の 3 つのレコードが挿入されていないのに、table2 のそれらに関連するレコードが挿入されているか、else レコードに挿入された別のレコードの値が間違っている場合があるなど) )。
name
スレッドコンストラクターで値を割り当てました。Main
クラスのこの関連部分は次のようになります。
PreparedStatement Stmt1=null; //for the first table
PreparedStatement Stmt2=null; //for the second table
private static Statement statement = null;
private static ResultSet resultSet = null;
String name=null;
String query1=null, query2=null;
try {
DBConnection.ConnectDB(); //connect to database
query1 = " insert into schema1.table1 values
(default,?,?)";
query2 = " insert into sechema1.table2 values (default,?,?)";
Stmt1 = DBConnection.con.prepareStatement(query1);
Stmt2 = DBConnection.con.prepareStatement(query1);
statement = DBConnection.con.createStatement();
resultSet = statement.executeQuery("select name from schema1.table1");
ExecutorService threadExecutor = Executors.newFixedThreadPool(10 );
while(resultSet.next())
{
myname=resultSet.getString("Column1");
MyRunnable task1 = new MyRunnable( myname);
threadExecutor.execute( task1 );
nameCounter++;
}
threadExecutor.shutdown();
// Wait until all threads are finish
while (! threadExecutor.isTerminated()) { }
System.out.println("Finished all threads");
DBConnection.con.close();
}// end try
catch (Exception e) {
e.printStackTrace();
}
MyRunnable クラスは次のとおりです。
public class MyRunnable implements Runnable{
private String threadName=null;
private int threadCounter; //to count how many names we have selected
MyRunnable2 (String name)
{
synchronized (this){ //I used synchronized as I want to avoid two threads
//taking the same value.
this.threadHostName=name;
this.threadCounter=Main.nameCounter; } //end synchronize
}
public void run()
{
// Here I make a call for the Class1 method1 that I want the thread to perform
} //end run()
} //end class MyRunnable
public void Class1 {
public void method1(String name)
{
//some calculations
//I used synchronized to make the DB records correctly inserted
synchronized(this) { //
for (int i = 0; i < Value.length; i++)
{
//here I need to insert values in table 2
try {
synchronized(this){
Main.Stmt2.setString (1, string1);
Main.Stmt2.setString (2, string2);
Main.Stmt2.executeUpdate();
}
catch (Exception e)
{
System.out.println("DB_Error:_"+ e.toString());
}
} //end for
// Here I made a call for method2 in Class2
} //end synchronized
} //end method1
} //end class1
ではClass2
、DB にレコードを挿入する必要もありClass1
ます。同期された inCalss2
内にあるため、既に同期されているはずです。マルチスレッドを扱うのはまったく初めてです。Parentheses
Class1
コード構造のどこが間違っていますか? 私は周りMain.Stmt2.setString
とMain.Stmt2.executeUpdate()
一緒に正しいですsynchronized
か?? マルチスレッドを処理するときに DB の整合性を維持するにはどうすればよいですか?