如何在 Java 中决定 wait() 的循环条件
how to decide the looping condition for wait() in Java
我理解 Java 中关于多线程的 wait(),并且根据文档,wait() 应该始终处于循环中。
我很难理解我们必须在循环中给出的条件是什么。通常,我见过:
synchornized(obj) {
while(some_condition) {
obj.wait();
}
// some other code
}
我很难理解在我们保持 wait() 的循环中使用的 "condition"。
我尝试实现一个场景,其中我创建了两个不同的线程(两个不同的 类 实现 Runnable 接口),用于打印奇数和偶数,例如:1 ,2 ,3,4,5, 6...
由于这是线程间通信,我们需要同步,所以我很难确定我必须为这两个不同的线程在循环中保持 wait() 的条件是什么。
非常感谢任何关于如何破译这个(我们保持循环的条件)的线索。
循环条件应该检查是否需要暂停执行(当前class的线程)
以著名的生产者-消费者问题为例,生产者在某种程度上看起来像
synchronized(mySharedObj)
{
while(mySharedObj.length==maxSize)
{
mySharedObj.wait();
}
}
如果 mySharedObj 上有 n 个生产者线程,当共享资源 (mySharedObj) 达到其限制时,所有生产者线程都将等待。
在这里,也许这几行会把你推向正确的方向,作为我之前评论的后续。
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!");
}
}
您提到了两个 类 所以它们的同步方法不会相互同步。这就是我们在监视器上同步的原因,因为这两个对象必须共享一些东西才能使它们 "hear" 彼此。
我理解 Java 中关于多线程的 wait(),并且根据文档,wait() 应该始终处于循环中。
我很难理解我们必须在循环中给出的条件是什么。通常,我见过:
synchornized(obj) {
while(some_condition) {
obj.wait();
}
// some other code
}
我很难理解在我们保持 wait() 的循环中使用的 "condition"。
我尝试实现一个场景,其中我创建了两个不同的线程(两个不同的 类 实现 Runnable 接口),用于打印奇数和偶数,例如:1 ,2 ,3,4,5, 6...
由于这是线程间通信,我们需要同步,所以我很难确定我必须为这两个不同的线程在循环中保持 wait() 的条件是什么。
非常感谢任何关于如何破译这个(我们保持循环的条件)的线索。
循环条件应该检查是否需要暂停执行(当前class的线程)
以著名的生产者-消费者问题为例,生产者在某种程度上看起来像
synchronized(mySharedObj)
{
while(mySharedObj.length==maxSize)
{
mySharedObj.wait();
}
}
如果 mySharedObj 上有 n 个生产者线程,当共享资源 (mySharedObj) 达到其限制时,所有生产者线程都将等待。
在这里,也许这几行会把你推向正确的方向,作为我之前评论的后续。
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!");
}
}
您提到了两个 类 所以它们的同步方法不会相互同步。这就是我们在监视器上同步的原因,因为这两个对象必须共享一些东西才能使它们 "hear" 彼此。