我试图获得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,混合模式,共享)
答案 0 :(得分:2)
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();
。