如何确定Java中wait()的循环条件
我理解Java中的wait()是关于多线程的,根据文档,wait()应该总是在一个循环中 我很难理解在循环中我们必须给出什么条件。通常,我看到:如何确定Java中wait()的循环条件,java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,我理解Java中的wait()是关于多线程的,根据文档,wait()应该总是在一个循环中 我很难理解在循环中我们必须给出什么条件。通常,我看到: synchornized(obj) { while(some_condition) { obj.wait(); } // some other code } 我很难理解我们保持等待()的循环中使用的“条件” 我试图实现一个场景,在这个场景中,我创建了两个不同的线程(两个实现Runnable接口的不同类),用于
synchornized(obj) {
while(some_condition) {
obj.wait();
}
// some other code
}
我很难理解我们保持等待()的循环中使用的“条件”
我试图实现一个场景,在这个场景中,我创建了两个不同的线程(两个实现Runnable接口的不同类),用于打印奇数和偶数,如:1、2、3、4、5、6
因为这是线程间的通信,我们需要同步,所以我很难将这两个不同线程在循环中保持wait()的条件联系起来
对于如何破译这个(我们在循环中保持的条件)的任何线索,我们都非常感激。循环条件应该检查执行(当前类的线程)是否需要暂时暂停 以著名的生产者消费者问题为例,生产者在哪里会看起来像
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!");
}
}
class LastPrintedMonitor{
公共布尔值waslast偶数=false;
}
类PrinterOdd实现可运行{
最后打印的监视器监视器;
公共打印机添加(上次打印的监视器监视器){
this.monitor=监视器;
}
@凌驾
公开募捐{
对于(int i=2;i<40;i+=2){
同步(监视器){
而(!monitor.waslast偶数){
试一试{
monitor.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
系统输出打印LN(i);
monitor.waslast偶数=false;
monitor.notifyAll();
}
}
}
}
类PrinterEven实现Runnable{
最后打印的监视器监视器;
公共打印机版本(上次打印的监视器){
this.monitor=监视器;
}
@凌驾
公开募捐{
对于(int i=1;i<40;i+=2){
同步(监视器){
while(monitor.waslast偶数){
试一试{
monitor.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
系统输出打印LN(i);
monitor.waslast偶数=true;
monitor.notifyAll();
}
}
}
}
公共类EvenOddPrinterDemo{
公共静态void main(字符串[]args){
LastPrintedMonitor监视器=新的LastPrintedMonitor();
线程奇数=新线程(新打印机添加(监视器));
线程偶数=新线程(新打印机偶数(监视器));
奇。开始();
偶数。开始();
试一试{
奇数连接();
偶数。join();
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“完成!”);
}
}
您提到了两个类,因此它们的同步方法不会相互同步。这就是我们在监视器上同步的原因,因为这两个对象必须共享一些东西才能让它们“听到”彼此的声音。获取同步方法“lock”的线程有什么原因吗可能无法继续,并希望将密钥临时分发给另一个线程,该线程可能会更改某些内容,以便分发密钥的线程能够继续?如果是-这是你的情况。是的。首先想象打印奇数的线程,打印1;然后这个线程应该等到另一个线程打印偶数,以此类推。因为它们必须运行:奇数,偶数,奇数,偶数,奇数,偶数…所以这里是你的条件:最后一个打印的数字是奇数吗?布尔值最后一次打印可能很奇怪?所以,您只检查线程打印偶数,并等待该布尔值设置为true。这只能在线程打印奇数时完成。因此,当线程打印偶数首先获得处理器时间并获得方法时,仍然可以将其传递给偶数打印线程。太棒了!我在做一个类似的方法,但是我将整个逻辑保持在无限循环中(对于这两个不同的线程)。我很难“猜”出应该是什么情况。仅供参考,这是我的问题--->谢谢你对这一点的洞察,了解了jist的实际含义。谢谢你的帮助。