[英]Threads occasionally blocking while writing to the same file
我试图使用两个单独的线程从两个文本文件(具有相同的行数,即10000)中读取文件,一个文件包含字符串,另一个文件包含整数。 之后,我想从结果集中的相应位置写入另一个文本文件(String,Integer)值,每个位置在不同的行上。 为此,我使用两个实现Runnable接口的类。
我面临的问题是,每次运行程序时,线程之一都有可能阻塞执行,并且我不明白为什么要考虑在一个线程中使用wait()和notify() synchronized
块。 更具体地说,有时程序会成功运行以完成执行过程,而在大多数情况下,它会在各个阶段停止(例如,在写入的10000行中大约有3000条记录,甚至有500条记录)。
citireInteger是对另一个读取Integer文件的线程的引用。
这是分别处理从String和Integer文件读取的类中的相关代码:
@Override
public void run(){
........
try {
pw = new PrintWriter(new BufferedWriter(new FileWriter("rezultat.txt", true)));
for(int i = 0; i < strings.size(); i++){
synchronized(this){
pw.write(strings.get(i));
}
synchronized(citireInteger){
citireInteger.notifyAll();
}
try{
synchronized(this){
wait();
}
} catch(InterruptedException e){
e.printStackTrace();
}
}
} catch(FileNotFoundException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
} finally{
pw.close();
}
synchronized(citireInteger){
citireInteger.notify();
}
}
读取Integer文件的线程:
public void run(){
...........
try{
pw = new PrintWriter(new BufferedWriter(new FileWriter("rezultat.txt", true)));
for(int i = 0; i < ints.size(); i++){
synchronized(this){
pw.write(ints.get(i) + '\n');
System.out.println(ints.get(i));
}
synchronized(citireString){
citireString.notifyAll();
}
try{
synchronized(this){
wait();
}
} catch(InterruptedException e){
e.printStackTrace();
}
}
} catch(FileNotFoundException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
} finally{
pw.close();
}
synchronized(citireString){
citireString.notify();
}
}
发生的情况是,一个线程正在另一线程上调用notifyAll
,然后在与自己的编写器同步以调用wait
之前被切换出去。 另一个线程进行写操作,在其写程序上进行同步,然后调用wait
。 然后,第一个线程再次进入,在其编写器上同步,并调用wait
。 有你的僵局。
最好让两个线程在同一个对象上进行同步写入。 最好将数据以线程安全的方式存储在内存中,并在从两个线程读取完成后从单个线程写入数据。
当您通知另一个线程时,另一个线程将仅在其他线程正在等待时看到它。 如果另一个线程在该同步块之外,则在收到通知后进入该同步块,然后它将等待一个通知,该通知不会发生,或者宁可发生,也不会在它开始等待之前发生。 很难真正确定此练习的目标是什么,但是我猜想这是两个线程轮流执行写操作的原因。 好的,那么,如何使synced(citireInt / String)块包含整个代码! 这样,试图获得锁的另一个线程将仅在另一个线程正在等待时才获得该锁。 我认为这不会保证任何阻塞,结果是两个线程都一一轮换。
编辑:完全不像我描述的那样,但是要点是同步的地方...
public void run()
{
...........
try
{
pw = new PrintWriter(new BufferedWriter(new FileWriter("rezultat.txt", true)));
synchronized(this)
{
for(int i = 0; i < ints.size(); i++)
{
pw.write(ints.get(i) + '\n');
System.out.println(ints.get(i));
synchronized (citireString)
{
citireString.notifyAll();
}
try
{
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
catch (Throwable e)
{
e.printStackTrace();
}
finally
{
pw.close();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.