我有一个创建多个无限线程的应用程序。每个线程读取一些信息,我使用线程池创建了一些任务(这很好)。
我添加了处理数组的附加函数,当它完成时,它将这些ArrayList
s 发送到将这些列表保存为文件的新线程。我已经以 3 种方式实现了保存,只有一种成功。我想知道为什么其他两种方式没有。
我创建了一个线程(通过
new Thread(Runnable)
),并给了它文件的数组和名称。在线程构造函数中,我创建PrintWriter
并保存了文件。它运行没有任何问题。(我有 1-10 个文件保存线程并行运行)。如果我将保存代码
outputStream.println(aLog);
放在Run
方法中,它永远不会到达它,并且在构造函数完成线程退出后。我将创建的可运行文件(文件保存)放在线程池中(保存的代码在
run()
方法中)。当我只发送 1 个任务(要保存 1 个文件)时,一切都很好。超过 1 个任务被添加到池中(非常快),创建了异常(在调试时我可以看到所有需要的信息都可用)并且一些文件没有保存。
有人可以解释不同的行为吗?谢谢
请看下面的代码。(从作为无限线程类的一部分的函数开始,该函数也将一些任务放入池中),在无限线程中创建池: 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)) ;
}
这是 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();}}
}
}