[英]Java wait notify with two threads as same class
我有一个FileReader类,像这样
public class FileReader extends Thread
{
private final Object lock = new Object();
public FileReader(String path, FileReaderCallback callback)
{
super(path);
this.path = path;
this.callback = callback;
}
@Override
public void run()
{
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
String info;
while ((info = reader.readLine()) != null)
{
synchronized (lock)
{
callback.onDone(path, info);
try
{
lock.wait();
}
catch (Exception ignored)
{
}
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void next()
{
synchronized (lock)
{
try
{
lock.notify();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
我有这个FileReader的两个实例,因为我想同时逐行读取两个文件。 问题是我的代码仅从两个文件读取一行,然后将暂停。
我这样在我的回调上调用该函数
public void onDone(String path, String info)
{
reader1.next();
reader2.next();
}
所以有什么问题?!
提前致谢
与next()
方法同步的lock
对象也可以在run
方法的while
循环中使用。 因此,不能从另一个线程中调用next()
方法的代码。
只需假设以下程序流程:
reader1
线程 reader2
线程 在某些时候,这两个线程之一开始。 假设reader1
线程首先启动:
lock
对象 reader1
和reader2
上调用next()
。 通话成功(但实际上没有操作) lock
对象上调用wait
。 等等... 在稍后的时间, reader2
线程启动
lock
对象 reader1.next()
它将尝试从其他线程将其lock
对象同步到reader1
,从而使程序进入死锁状态。 为了解决此问题,我真的建议您过度处理如何逐行同步的概念。 一个简单的解决方法可能是对next()
方法使用不同的锁变量。
您正在将侦听器回叫,同时将锁定保持在同一对象lock
。 这将允许在调用等待之前调用通知。 这将使您的线程永远等待。
你应该,
您正面临经典的僵局情况。 假设第一锁为lock1
,第二锁为lock2
。 在您的第一个实例中,锁定状态可以表示为:
synchronized (lock1) {
// start of onDone
synchronized (lock1) {
}
synchronized (lock2) {
}
// end of onDone
}
在第二个中,它是这样的:
synchronized (lock2) {
// start of onDone
synchronized (lock1) {
}
synchronized (lock2) {
}
// end of onDone
}
正如其他答案所建议的那样,您应该完善自己的逻辑。
设计中的另一个缺陷是: 您也没有考虑可能的虚假唤醒。 通常,您应该将wait()
调用放入while
循环中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.