我遇到一个问题“创建2个线程,一个将数据写入文件(从程序中定义的字符串),另一个将读取同一文件中的数据并将其显示在控制台上”。这是我的实现,但是陷入了无限循环
import java.io.*
class ReaderWriter {
int ch;
FileInputStream fin;
FileOutputStream fout;
boolean rdrblocked = false;
static volatile boolean running;
static volatile boolean eof = false;
String s = "This will end up in a file in the same order as it appears here or else we can conclude that there is some discrepancy related to some race condition stuff";
byte b[] = s.getBytes();
int length = b.length;
void writer() throws Exception {
fout = new FileOutputStream("Demo.txt");
for (int i = 0; i < length; i++) {
fout.write(b[i]);
if (rdrblocked) {
synchronized(this) {
rdrblocked = false;
notify();
}
}
}
eof = true;
while (running) {
synchronized(this) {
rdrblocked = false;
notify();
}
}
fin.close();
}
void reader() throws Exception {
running = true;
fin = new FileInputStream("Demo.txt");
if (fin.available() > 0) {
while ((ch = fin.read()) != -1) {
System.out.print((char) ch);
while (fin.available() == 0 && !eof) {
synchronized(this) {
rdrblocked = true;
wait();
}
}
}
}
running = false;
fin.close();
}
}
class Writercall implements Runnable {
Thread t;
ReaderWriter obj;
Writercall(ReaderWriter obj) {
this.obj = obj;
t = new Thread(this, "Reader");
t.start();
}
public void run() {
try {
obj.writer();
} catch (Exception e) {}
}
}
class Readercall implements Runnable {
Thread t;
ReaderWriter obj;
Readercall(ReaderWriter obj) {
this.obj = obj;
t = new Thread(this, "Writer");
t.start();
}
public void run() {
try {
obj.reader();
} catch (Exception e) {}
}
}
class RWDemo {
public static void main(String args[]) throws Exception {
ReaderWriter obj1 = new ReaderWriter();
Readercall r = new Readercall(obj1);
Writercall w = new Writercall(obj1);
try {
r.t.join();
w.t.join();
} catch (Exception e) {}
}
}
任何帮助和更好的实现方式将受到赞赏。 P.S:我使用了volatile以及isAAlive(),但它不起作用,我认为问题是在writer的while循环中,读取器将布尔变量更新为false并没有反映在读取器中。 P.P.S:是的,我知道这是实现并发的低效率方法,但是我很好奇这是否可行。 编辑:我已经按照muradm的建议更新了代码。仍然欢迎对代码进行任何改进。(更新的代码链接在上面)
答案 0 :(得分:0)
问题是您试图立即打开同一文件。只是给您一个想法:
// omitted
void reader() throws Exception {
// reader waits before writer notify
// writer notifies reader to wake up
synchronized (this) {
rdrblocked = true;
wait();
}
while (!new File("Demo.txt").exists() && running) {
Thread.sleep(10);
}
fin = new FileInputStream("Demo.txt");
if (fin.available() > 0) {
while ((ch = fin.read()) != -1) {
System.out.print((char) ch);
}
}
// omitted
即由于文件开头不存在,因此读写器可能会从OS获取不同的句柄。让读者检查文件是否存在并等待其存在将解决问题,但是仍然...
但是,这似乎不是一个好的解决方案。您的目的尚不清楚:
EOF
,一旦读者到达EOF
,您的句柄就应该无效,尽管作者可能在读者的RandomAccessFile
事件之后继续写入文件。 如果背后有实际任务,您将需要寻找更复杂的解决方案以实现对单个文件的可靠读取/写入。像wait()
一样。
此外,如果您正在计算notify()
和wait()
,那么notify()
应该在wait()
之前出现,否则,如果您在数据之后notified()
从文件中读取,然后实际上是写者wait()
,甚至连读者都开始读wait()
。即服务员会错过在value
呼叫之前发生的通知。