[英]Java wait notify with two threads as same class
I have a FileReader class which is like this 我有一个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();
}
}
}
}
And I have two instance of this FileReader because I want to read two file line by line simultaneously. 我有这个FileReader的两个实例,因为我想同时逐行读取两个文件。 The problem is my code only reads one line from both file and then it's going to pause.
问题是我的代码仅从两个文件读取一行,然后将暂停。
I Call the function on my callback like this 我这样在我的回调上调用该函数
public void onDone(String path, String info)
{
reader1.next();
reader2.next();
}
So what's the problem?! 所以有什么问题?!
Thanks in advance 提前致谢
Your lock
object which you synchronize the next()
method to is also used within your while
loop in the run
method. 与
next()
方法同步的lock
对象也可以在run
方法的while
循环中使用。 Therefore, the code of your next()
method cannot be called from within another thread. 因此,不能从另一个线程中调用
next()
方法的代码。
Just assume the following program flow: 只需假设以下程序流程:
reader1
thread reader1
线程 reader2
thread reader2
线程 At some time one of those two threads start. 在某些时候,这两个线程之一开始。 Let's assume
reader1
thread starts first: 假设
reader1
线程首先启动:
lock
object lock
对象 next()
on reader1
and reader2
. reader1
和reader2
上调用next()
。 This call is successful (but actually a no-op) wait
on its lock
object. lock
对象上调用wait
。 And waits... At some later time the reader2
thread starts 在稍后的时间,
reader2
线程启动
lock
object lock
对象 reader1.next()
it tries to synchronize to the reader1
its lock
object from a different thread, thus putting your program into a deadlock state. reader1.next()
它将尝试从其他线程将其lock
对象同步到reader1
,从而使程序进入死锁状态。 To solve this problem I would really suggest to overwork the concept of how you perform the line-by-line synchronization. 为了解决此问题,我真的建议您过度处理如何逐行同步的概念。 An easy fix would probably be to use a different lock variable for your
next()
method. 一个简单的解决方法可能是对
next()
方法使用不同的锁变量。
You are calling listener call back while holding the lock on the same object lock
. 您正在将侦听器回叫,同时将锁定保持在同一对象
lock
。 This will allow notify to be invoked before a wait is invoked. 这将允许在调用等待之前调用通知。 This will make your thread wait forever.
这将使您的线程永远等待。
You should, 你应该,
You are facing a classic deadlock scenario. 您正面临经典的僵局情况。 Let the first lock be
lock1
and the second lock be lock2
. 假设第一锁为
lock1
,第二锁为lock2
。 In your first instance, the lock status can be expressed as follows: 在您的第一个实例中,锁定状态可以表示为:
synchronized (lock1) {
// start of onDone
synchronized (lock1) {
}
synchronized (lock2) {
}
// end of onDone
}
and in second one, it is like this: 在第二个中,它是这样的:
synchronized (lock2) {
// start of onDone
synchronized (lock1) {
}
synchronized (lock2) {
}
// end of onDone
}
You should refine your logic, as other answers suggest. 正如其他答案所建议的那样,您应该完善自己的逻辑。
Another flaw in your design is; 设计中的另一个缺陷是: you are also not considering possible spurious wakeups.
您也没有考虑可能的虚假唤醒。 Generally, you should put your
wait()
calls in a while
loop. 通常,您应该将
wait()
调用放入while
循环中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.