提问人:Avenger 提问时间:6/16/2023 更新时间:6/16/2023 访问量:58
线程处于无限等待状态
Thread is going in infinite wait state
问:
给定一个整数 N,任务是编写一个 Java 程序,使用两个线程按递增顺序打印前 N 个自然数。但是,输出仅显示数字 1,因为线程正在进入无限循环,这是用户无法调试的。
public class OddEven {
static int totalNos;
static int counter = 1;
static Runnable odd = new Runnable() {
@Override
public void run() {
synchronized (this) {
while(counter < totalNos) {
while (counter%2==0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(counter + " ");
counter++;
notify();
}
}
}
};
static Runnable even = new Runnable() {
@Override
public void run() {
synchronized (this) {
while(counter < totalNos) {
while (counter%2==1) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(counter + " ");
counter++;
notify();
}
}
}
};
public static void main(String[] args) {
System.out.println("Enter the total no's");
Scanner scObj = new Scanner(System.in);
totalNos = scObj.nextInt();
scObj.close();
Thread oddT1 = new Thread(odd);
Thread evenT1 = new Thread(even);
oddT1.start();
evenT1.start();
}
}
答:
1赞
Solomon Slow
6/16/2023
#1
两个对象之间没有同步。你的两个对象中的每一个,都在它自己身上同步,在它自己身上等待,并通知它自己。或者,更准确地说,如果它到达那个点,它会通知自己,但它没有到达那里,因为另一个线程永远不会通知它。even
odd
您需要让两个线程使用相同的对象进行同步。例如;
public class OddEven {
static final Object lock = new Object();
static int totalNos;
static int counter = 1;
static Runnable odd = new Runnable() {
@Override
public void run() {
synchronized (lock) {
...
lock.wait();
...
lock.notify();
}
}
}
.
.
.
}
评论
1赞
user16320675
6/16/2023
我建议添加 - 通常我们不希望外部代码能够通知它(可能对所有字段都有效......private
lock
1赞
Holger
6/16/2023
你如何使用“自我”来避免“”很奇怪。此外,你的措辞将初学者推向了错误的方向,认为 和 是对象,而不是包含对对象的引用的变量。this
even
odd
0赞
Solomon Slow
6/16/2023
@Holger,这很有趣,因为我通常是第一个提请注意变量与对象和对象引用之间的区别的人,而不理解它是某人问题的根源;但这里的情况并非如此。我想提请注意这样一个事实,即每个线程都有自己独特的委托,并且很自然地叫出它们的名字。我敢肯定,我们所有人都会使用变量的名称来识别它们所指的对象,而不可能误解哪个对象的含义。
0赞
Solomon Slow
6/16/2023
@Holger,Re,“'self'来避免'this'”,我并没有有意识地试图避免任何事情,尽管我一直觉得与其他语言相比,Java 有些尴尬。如果我不被允许说“自我”,我将不得不花更多的文字来表达“它自己的自我”所包含的想法。此外,如果我只是简单地说,“每个对象都同步”,我就不会告诉 OP 任何他们不知道的事情。这在他们自己的代码中是明确的。this
self
this
1赞
Holger
6/16/2023
在 和 调用的情况下,它们在 上被调用并不是那么明显。但是,是的,重要的一点不是这两个线程在“this”上同步,而是“this”指的是不同的对象。这是已传递给两个构造函数的两个实例。但也许,你的措辞对于初学者来说更容易掌握;从 OP 那里获得反馈是否有帮助将非常有用......wait()
notify()
this
Runnable
Thread
评论
counter
volatile
volatile
synchronized
wait
synchronized
wait
wait