我有一个需要 Java 多线程的程序。该Main
函数对 MySQL DB 进行查询以选择一个值name
并一次将一个值发送name
到每个线程。
每个线程都会进行依赖于此的操作name
。该run
函数调用一个方法,例如,method1
该Class1
方法执行一些操作并在 table2 中的 DB 中插入值,此外,它还调用另一个方法,method2
该方法在 table1 中执行操作和插入。
数据库包含表 1 和表 2,一对多。但是我还没有连接表,它们直到现在都是分开的。但是其中有一列table2
反映了table1中的某个记录table2
属于哪个记录。我在 table2 中的数据库是正确的,但在 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
中,我还需要向数据库中插入记录,我在Class1
. Calss2
已经应该是同步的,因为它在同步Parentheses
的 in 中Class1
。我对处理多线程完全陌生。
我的代码结构有什么问题?我在周围Main.Stmt2.setString
和Main.Stmt2.executeUpdate()
周围是否正确synchronized
?处理多线程时如何保持数据库完整性?