简体   繁体   English

Java多线程文件保存

[英]Java multi threading file saving

I have an app that created multiple endless threads. 我有一个创建多个无尽线程的应用程序。 Each thread reads some info and I created some tasks using thread pool (which is fine). 每个线程读取一些信息,并且我使用线程池创建了一些任务(很好)。

I have added additional functions that handle arrays, when it finishes, its send those ArrayList s to new thread that save those lists as files. 我添加了其他处理数组的功能,完成处理后,会将那些ArrayList发送到新线程,这些线程将这些列表另存为文件。 I have implemented the saving in 3 ways and only one of which succeeds. 我已经通过3种方式实现了节能,但只有一种成功了。 I would like to know why the other 2 ways did not. 我想知道为什么其他两种方式没有。

  1. I created a thread (via new Thread(Runnable) ) and gave it the array and name of the file. 我创建了一个线程(通过new Thread(Runnable) ),并为其指定了数组和文件名。 In the thread constructor I create the PrintWriter and saved the files. 在线程构造函数中,我创建PrintWriter并保存了文件。 It ran without any problems. 它运行没有任何问题。 ( I have 1-10 file save threads runing in parallel). (我有1-10个文件保存线程并行运行)。

  2. If I place the save code outputStream.println(aLog); 如果我放置保存代码outputStream.println(aLog); in the Run method, it never reaches it and after the constructor finishes the thread exit. Run方法中,它永远不会到达它,并且在构造函数完成线程退出之后。

  3. I place the created runnables (file save) in a thread pool (and code for saving is in the run() method). 我将创建的可运行对象(文件保存)放在线程池中(保存的代码在run()方法中)。 When I send just 1 task (1 file to save), all is fine. 当我仅发送1个任务(保存1个文件)时,一切都很好。 More than 1 task is being added to the pool (very quickly), exceptions is created (in debug time I can see that all needed info is available) and some of the files are not saved. 超过1个任务(非常快速)被添加到池中,创建了异常(在调试时我可以看到所有需要的信息都可用),并且某些文件没有保存。

Can one explain the difference behavior? 可以解释差异行为吗? Thanks 谢谢

Please see code below. 请参见下面的代码。 (starting with function that is being part of an endless thread class that also place some tasks in the pool), the pool created in the endless thread: ExecutorService iPool = Executors.newCachedThreadPool(); (从作为无限线程类的一部分的函数开始,该函数还将一些任务放入池中),该池在无限线程中创建:ExecutorService iPool = Executors.newCachedThreadPool();

private void logRate(double r1,int ind){
 historicalData.clear();
    for (int i = 499; i>0; i--){
      // some Code

     Data.add(0,array1[ind][i][0] + "," + array1[ind][i][1] + "," + 
                          array1[ind][i][2] + "," + array1[ind][i][3] + "," +
                          array2[ind][i] + "\n" );
     }
      // first item
      array1[ind][0][0] = r1; 
      array1[ind][0][1] = array1[ind][0][0] ;
      array1[ind][0][2] = array1[ind][0][0] ;
      array2[ind][0] = new SimpleDateFormat("HH:mm:ss yyyy_MM_dd").format(today); 

      Data.add(0,r1+","+r1+","+r1+","+r1+ "," + array2[ind][0] + '\n') ;

      // save the log send it to the pool (this is case 3)
      //iPool.submit(new FeedLogger(fName,Integer.toString(ind),Data));
      // Case 1 and 2 
      Thread fl = new Thread(new FeedLogger(fName,Integer.toString(ind),Data)) ;
    }

here is the FeedLogger class: 这是FeedLogger类:

public class FeedLogger implements Runnable{
private List<String> fLog = new ArrayList<>() ;
PrintWriter outputStream = null;
String asName,asPathName;

public FeedLogger(String aName,String ind, List<String> fLog) {
this.fLog = fLog;
this.asName = aName;

try {
    asPathName = System.getProperty("user.dir") + "\\AsLogs\\"  + asName + "\\Feed" + ind 
                                    + ".log" ;

     outputStream = new PrintWriter(new FileWriter(asPathName));
     outputStream.println(fLog); Case 1 all is fine
     outputStream.flush(); // Case 1 all is fine
     outputStream.close(); Case 1 all is fine

}
catch (Exception ex) {
    JavaFXApplication2.logger.log(Level.SEVERE, null,asName + ex.getMessage());
 }
}

@Override
public void run()
{
 try{
    outputStream.println(fLog); // Cas2 --> not reaching this code, Case3 (as task) create 
                                                     exception when we have multiple tasks
    outputStream.flush();
    } 
  catch (Exception e) {
      System.out.println("err in file save e=" + e.getMessage() + asPathName + " feed size=" +  
                          fLog.size()); 
      JavaFXApplication2.logger.log(Level.ALL, null,asName + e.getMessage());
  } 

    finally {if (outputStream != null) {outputStream.close();}}
    }
  } 

您需要在Thread实例上调用start()使其实际执行某些操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM