2

我正在尝试在 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++;
  }

}

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

字符串 #1
字符串 #2
字符串 #3

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

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

java 版本 "1.7.0_21" Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) Client VM (build 23.21-b01, 混合模式, 共享)

4

3 回答 3

2

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

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

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

于 2013-05-12T19:16:52.503 回答
0

为了解决您的直接问题(关于单线程示例),请在添加此语句之后立即mt.start();mt.join();

于 2013-05-13T03:47:35.147 回答
0

每当您在 java 中对文件或 IO 的输出做任何事情时,您必须始终关闭输出设备;在这种情况下,似乎您正在使用 BufferedWriter 作为输出,因此无论您要写入文件的任何位置,最后只需键入

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

这应该将您的所有信息写入文件。希望这可以帮助!!

于 2013-05-12T19:16:44.103 回答