我对Java中的线程编程很陌生,我目前正在构建一个应用程序,其中包括许多SQL脚本并调用它们。
对于每个文件,它执行调用,如果抛出一些异常,它会捕获它并使用由FileWriter构造的PrintWriter将相关信息写入日志文件。
当然,所有这些都是通过for循环进行的。
当文件写入比其余操作慢得多时,问题就出现了:在写入结束之前,该过程结束,因此文件最终未完成。
我已经尝试过使用synchronized代码块,wait()和notify()方法,但还没有成功。我附上了代码的摘录:
boolean waiting_for_end_of_file_writing = true;
FileWriter fw = new FileWriter(FICHIER_LOG_ERREURS_SQL, true);
PrintWriter pw = new PrintWriter(fw);
for(int j = 0; j < input_paths_sql.length; j++){
System.out.println("Script " + m + " dont " + input_paths_sql.length
+ " avec nom " + oftp.get_locals()[j]
+ " à exécuter");
try {
Generic_library.Call_Fichier_SQL(oftp.get_locals()[j],
ojdbc.get_sybase_connection());
} catch (IOException ex) {
Logger.getLogger(Form_table_clients.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
pw.write("Exception en fichier " + oftp.get_locals()[j] + "\r\n");
ex.printStackTrace(pw);
pw.write("\r\n");
Logger.getLogger(Form_table_clients.class.getName()).log(Level.SEVERE, null, ex);
}
m++;
}
synchronized(pw){
pw.write(" ----------------- END OF UPDATE PROCESS ----------------- \r\n");
waiting_for_end_of_file_writing = false;
pw.notify();
}
synchronized(pw){
try {
while(waiting_for_end_of_file_writing)
pw.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Form_table_clients.class.getName()).log(Level.SEVERE, null, ex);
}
}
return success;
所以这样做: - Generic_library.Call_Fichier_SQL()将路径和Connection对象接受到DataBase,并将它们与CallableStatement一起使用来调用脚本
我的目标是在完成“返回成功”行之前停止该线程,该行完成该方法,直到pw完成所有写入并最终执行该行
pw.write(“----------------- END OF UPDATE PROCESS ----------------- \ r \ n“个);
否则,如上所述,日志文件最终不完整。
感谢您给我的任何帮助。同样,如果任何人都想出一些想法来绕过这个问题(可能是通过一些线程安全的方式来写入文件),它也可以做到。
答案 0 :(得分:0)
写完后,你需要冲洗它,或者最好关闭()它。如果你让应用程序继续运行,它可以刷新并清理资源本身(在一些随机的时间),但你应该自己这样做,以便你知道它已经完成。
简而言之,当你完成它们时,总是关闭Stream / Reader / Writer / Statement / Connection / ResultSet。 (实际上任何可以接近的东西())
在您的情况下,我会删除两个已同步的块并使用pw.flush();
虽然println()速度不快,但它应该比JDBC数据库中的SQL查询快10倍到100倍。