Java线程写入文件

时间:2013-05-12 19:12:49

标签: java multithreading file

我试图获得Java线程和与共享对象同步的一些经验,并执行简单的锁定。 我想要做的是创建Java应用程序,它将时间戳(或分钟)插入到具有2个不同线程的文本文件中:一个线程将只插入奇数时间戳(或分钟)到文件,另一个线程将只插入偶数时间戳到同一个文件。当一个线程插入时,另一个线程无法插入并等待通知。文件内容必须在进程关闭后(控制台中的Ctrl + C),如下所示:

2013-05-10 21:37:02  
2013-05-10 21:37:03   
2013-05-10 21:37:04   
2013-05-10 21:37:05

2013-05-10 21:37    
2013-05-10 21:38   
2013-05-10 21:39   
2013-05-10 21:40 

首先,我想创建一个将在文件中插入行的线程,并且无法弄清楚出了什么问题。这是我的代码:

import java.io.*;

public class MyFileWriter
{
 private FileWriter fwriter;
 private BufferedWriter bufwriter;

 public FileWriter getWriter()
 {
    return this.fwriter;
  }

  public void setWriter(FileWriter pfwriter)
  {
     this.fwriter = pfwriter;
  }

  public BufferedWriter getBufWriter()
  {
    return this.bufwriter;
  }

  public void setBufWriter(BufferedWriter pbfwriter)
  {
    this.bufwriter = pbfwriter;
  }

  public static void main(String[] args)
  {
    MyFileWriter myfile = new MyFileWriter();

try
{ 
 FileWriter fstream = new FileWriter("output.txt");
 myfile.setWriter(fstream);
 BufferedWriter out = new BufferedWriter(fstream);
 myfile.setBufWriter(out);
}
catch (IOException e)
{
 System.out.println("Error : "+e.getMessage());
}

MyThread mt = new MyThread();
mt.setBufWriter(myfile.getBufWriter());
mt.start();

    }
  }

class MyThread extends Thread
{ 
  private BufferedWriter bout;

  private int count = 1;

   public BufferedWriter getBufWriter()
  {
    return this.bout;
  }

   public void setBufWriter(BufferedWriter pbout)
   {
     this.bout = pbout;
   }

   public void run()
   {
    try
   {
     this.sleep(1000);
   }
   catch(InterruptedException e)
   {
     System.out.println("Error : "+e.getMessage());
   }

   try
   {
    this.bout.write("String # "+count);
    this.bout.newLine();
   }
   catch(IOException e)
   {
    System.out.println("Error : "+e.getMessage());
   }

   this.count++;
  }

}

import java.io.*; public class MyFileWriter { private FileWriter fwriter; private BufferedWriter bufwriter; public FileWriter getWriter() { return this.fwriter; } public void setWriter(FileWriter pfwriter) { this.fwriter = pfwriter; } public BufferedWriter getBufWriter() { return this.bufwriter; } public void setBufWriter(BufferedWriter pbfwriter) { this.bufwriter = pbfwriter; } public static void main(String[] args) { MyFileWriter myfile = new MyFileWriter(); try { FileWriter fstream = new FileWriter("output.txt"); myfile.setWriter(fstream); BufferedWriter out = new BufferedWriter(fstream); myfile.setBufWriter(out); } catch (IOException e) { System.out.println("Error : "+e.getMessage()); } MyThread mt = new MyThread(); mt.setBufWriter(myfile.getBufWriter()); mt.start(); } } class MyThread extends Thread { private BufferedWriter bout; private int count = 1; public BufferedWriter getBufWriter() { return this.bout; } public void setBufWriter(BufferedWriter pbout) { this.bout = pbout; } public void run() { try { this.sleep(1000); } catch(InterruptedException e) { System.out.println("Error : "+e.getMessage()); } try { this.bout.write("String # "+count); this.bout.newLine(); } catch(IOException e) { System.out.println("Error : "+e.getMessage()); } this.count++; } }

我希望在创建并启动MyThread mt之后,线程将插入到文件“output.txt”字符串中,在命令提示符中执行Ctrl + C之后,我会有类似这样的内容:

String #1
String #2
String #3

但应用程序由于某种原因本身完成,我只得到空文件(当我启动应用程序时,有时文件有“String#1”,但大部分是空的)。 谁能告诉我我做错了什么?

操作系统:Windows XP SP3,Java版本:

java版“1.7.0_21” Java(TM)SE运行时环境(版本1.7.0_21-b11) Java HotSpot(TM)客户端VM(版本23.21-b01,混合模式,共享)

3 个答案:

答案 0 :(得分:2)

嗯,好几件事。首先,你的run()方法只打印一行,你只创建一个线程,所以我不确定你认为其他行将来自哪里。 run()将在新线程中运行一次,就是这样。我猜你假设run()将在循环中被调用,但它不会。

其次,您正在使用BufferedWriter,此类在将数据发送到文件之前缓冲(保留)写入流的数据,以便可以一次写入大量数据,为了效率。问题是,如果您没有手动关闭或刷新BufferedWriter - 而您没有 - 那么您的输出将永远不会写入文件。如果在每次写入flush()后添加对BufferedWriter的调用,您将看到所有输出都在文件中结束 - 尽管这确实消除了首先使用BufferedWriter的原因!

更好的解决方案是等待写入线程终止(使用Thread.join()然后关闭main()中的文件。

答案 1 :(得分:0)

无论何时对java中的文件输出或IO进行任何操作,都必须始终关闭输出设备;在这种情况下,似乎您使用BufferedWriter作为输出,因此无论您在何处写入文件,最后只需键入

 <output>.close();
 <output> being the variable you use.

这应该将您的所有信息写入文件。 HOpe这有帮助!!

答案 2 :(得分:0)

要解决您的直接问题(关于单线程示例),后立即 mt.start();添加此声明mt.join();