我在Java中了解了多线程的wait(),并且根据文档,wait()应该始终处于循环中。
我很难理解我们必须在循环中给出的条件是什么。通常情况下,我看到了:
synchornized(obj) {
while(some_condition) {
obj.wait();
}
// some other code
}
我很难理解在我们保持wait()的循环中使用的“条件”。
我试图实现一个场景,我创建了两个不同的线程(实现Runnable接口的两个不同的类),用于打印奇数和偶数,如:1,2,3,4,5,6 ......
由于这是线程间通信而且我们需要同步,因此我很难将这两个不同线程的循环保持wait()的条件联系起来。
关于如何破译这一点(我们保持循环的条件)的任何线索都非常感激。
答案 0 :(得分:1)
循环条件应检查是否需要临时暂停执行(当前类的线程)。
举一个着名的生产者 - 消费者问题的例子,生产者在某种程度上看起来像
synchronized(mySharedObj)
{
while(mySharedObj.length==maxSize)
{
mySharedObj.wait();
}
}
如果 mySharedObj 上有n个生产者线程,则当共享资源(mySharedObj)达到其限制时,所有人都将等待。
答案 1 :(得分:1)
在这里,也许这几行会推动你朝着正确的方向前进,作为我之前评论的后续行动。
class LastPrintedMonitor {
public boolean wasLastEven = false;
}
class PrinterOdd implements Runnable {
LastPrintedMonitor monitor;
public PrinterOdd(LastPrintedMonitor monitor) {
this.monitor = monitor;
}
@Override
public void run() {
for (int i = 2; i < 40; i += 2) {
synchronized (monitor) {
while (!monitor.wasLastEven) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
monitor.wasLastEven = false;
monitor.notifyAll();
}
}
}
}
class PrinterEven implements Runnable {
LastPrintedMonitor monitor;
public PrinterEven(LastPrintedMonitor monitor) {
this.monitor = monitor;
}
@Override
public void run() {
for (int i = 1; i < 40; i += 2) {
synchronized (monitor) {
while (monitor.wasLastEven) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
monitor.wasLastEven = true;
monitor.notifyAll();
}
}
}
}
public class EvenOddPrinterDemo {
public static void main(String[] args) {
LastPrintedMonitor monitor = new LastPrintedMonitor();
Thread odd = new Thread(new PrinterOdd(monitor));
Thread even = new Thread(new PrinterEven(monitor));
odd.start();
even.start();
try {
odd.join();
even.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Done!");
}
}
您提到了两个类,因此它们的同步方法不会彼此同步。这就是我们为什么要在显示器上进行同步的原因,因为必须有这两个对象共享的内容才能使它们听到&#34;听到&#34;彼此。