Java同步问题:PrintWriter比其他操作慢

Java同步问题:PrintWriter比其他操作慢,java,synchronization,printwriter,Java,Synchronization,Printwriter,我对Java中的线程编程非常陌生,目前我正在构建一个应用程序,其中包括获取大量SQL脚本并调用它们 对于每个文件,它执行调用,并且在抛出某个异常的情况下,它会捕获该异常,并使用由FileWriter构造的PrintWriter将相关信息写入日志文件 当然,所有这些都是由for循环进行的 当比其他操作慢的文件写入未成功完成时,问题就会出现:该过程在写入结束之前完成,因此文件最终未完成 我尝试过使用同步代码块、wait()和notify()方法,但还没有成功。我附上代码摘录: boolean

我对Java中的线程编程非常陌生,目前我正在构建一个应用程序,其中包括获取大量SQL脚本并调用它们

对于每个文件,它执行调用,并且在抛出某个异常的情况下,它会捕获该异常,并使用由FileWriter构造的PrintWriter将相关信息写入日志文件

当然,所有这些都是由for循环进行的

当比其他操作慢的文件写入未成功完成时,问题就会出现:该过程在写入结束之前完成,因此文件最终未完成

我尝试过使用同步代码块、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;
boolean等待\u文件的\u结束\u写入=true;
FileWriter fw=新的FileWriter(FICHIER\u LOG\u errurers\u SQL,true);
PrintWriter pw=新的PrintWriter(fw);
对于(int j=0;j
这就是: -Generic_library.Call_Fichier_SQL()获取数据库的路径和连接对象,并将其与CallableStatement一起使用以调用脚本

我的目标是在线程到达“return success”行之前停止线程,该行将完成方法,直到pw完成所有写入并最终执行该行

pw.write(“--------------更新过程结束-------------------\r\n”)

否则,如上所述,日志文件将不完整


谢谢你能给我的任何帮助。同样,如果有人能想出一些绕过该问题的办法(例如,可以通过使用某种线程安全的方式写入文件),它也会产生同样的效果。

当您完成写入时,您需要刷新它,或者最好关闭()它。如果您让应用程序运行,它可以刷新和清理资源本身(在某个随机时间),但您应该始终自己这样做,这样您就知道它已经完成了

简而言之,在完成流/读/写/语句/连接/结果集时,始终关闭它们。(事实上,任何可以接近的东西()

在您的情况下,我将删除两个同步块并使用
pw.flush()


虽然println()并不快,但它应该比来自JDBC数据库的SQL查询快10到100倍。

正如@PeterLawry所说,您需要刷新一个具有内部缓冲区的PrintWriter。但更好的解决方案是用真正的日志框架(如Log4J或LogBack)替换PrintWriter。花了这么长时间环顾四周,才找到这么简单的答案:-/万分感谢,@PeterLawrey和kdgregory