我正在尝试创建一个运行多个并行读取器和编写器的程序。我使用ExecutorService
类在循环中启动一些线程,Writer类的run()
方法只调用两个方法StartWrite()
和EndWrite()
,而对于Reader类,{{1 }和StartRead()
。这些方法包含在监视器中。
这是监视器:
EndRead()
但是有一个问题:程序在写入和读取预期数量的数据之前结束。例如,如果我启动20个编写器和20个读取器线程,我希望写入和读取20个数字,但只有10个。如果我再次运行程序(datos.dat已经创建),它会继续写入和读取,然后写入20个数字。
测试:
第一次运行
第二轮
怎么了?我怎样才能让它正常工作?
编辑:每次读者完成阅读并且多次打印相同数量的读者时,我都尝试打印读取器的数量。这个不不应该发生吗? public class RWMonitorAN {
static int readers = 0;
static boolean writing = false;
public static RandomAccessFile f;
public static int n = 0;
private final ReentrantLock mylock = new ReentrantLock();
private final Condition toWrite = mylock.newCondition();
private final Condition toRead = mylock.newCondition();
public RWMonitorAN()
{
try { f = new RandomAccessFile("datos.dat", "rw"); } catch (IOException e) {}
}
void StartRead() {
mylock.lock();
try
{
if (writing)
try {
toRead.wait();
toWrite.wait();
} catch (InterruptedException e) {}
readers++;
try
{
f.seek(0);
while (f.getFilePointer()<f.length())
System.out.print(f.readInt()+" ");
System.out.println();
} catch (IOException e) { e.printStackTrace(); }
}
finally { mylock.unlock(); }
}
void EndRead() {
mylock.lock();
try
{
readers--;
if (readers == 0)
toWrite.signal();
}
finally { mylock.unlock(); }
}
void StartWrite() {
mylock.lock();
try
{
if (writing || readers != 0)
try {
toWrite.wait();
} catch (InterruptedException e) {}
writing = true;
try
{
f.writeInt(n);
} catch(IOException e) {}
n++;
}
finally { mylock.unlock(); }
}
void EndWrite() {
mylock.lock();
try
{
writing = false;
toWrite.signal();
toRead.signal();
}
finally { mylock.unlock(); }
}
在代码的受锁保护部分执行。
答案 0 :(得分:0)
您到处都在捕捉您的例外情况,不会在任何地方报告,也不会做任何其他事情来为他们服务。 “使其正常工作”的第一件事可能是检查是否存在异常调用。例如,如果在Java中的一个数据结构上使用多个迭代器,它可能会在开始时抛出concurrentModificationException,以防止将来出现意外行为。
如果使用seek(0)将每个新文件设置到文件的最开头,那么从文件中使用多个阅读器有什么意义呢?而您的读者似乎试图阅读整个文件
while (f.getFilePointer()<f.length())
System.out.print(f.readInt()+" ");
并且您的作者尝试在
中读取单个int f.writeInt(n);
所以如果你开始了n个线程,我就不希望读取n个数字。
最后,您是否考虑过在startRead解锁mylock之后但在EndRead再次锁定它之前启动另一个编写器/阅读器时会发生什么?为什么不把startRead的逻辑放在startRead方法的末尾呢?