首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >程序停止:等待()和通知()

问程序停止:等待()和通知()
EN

Stack Overflow用户
提问于 2015-05-09 14:57:03
回答 1查看 169关注 0票数 2

我试图做到这一点:创建两个不同的线程,一个打印奇数,一个打印偶数。一旦一个线程打印了一个数字,它就必须等待另一个线程,以此类推。

为了实现这一点,我使用了同步块以及等待()和通知()。

我正在创建一个类,它的对象将被用来传递给两个线程中的同步块。

以下是代码:

->这是使用的对象,它将被传递给同步块。

代码语言:javascript
复制
package com.vipin.multithread.variousdemos;

    public class SyncObject {

        public SyncObject () {  

        }
}

奇线:

代码语言:javascript
复制
package com.vipin.multithread.variousdemos;

public class OddThread implements Runnable {

private Thread t;
int index=0;
SyncObject so=null;

int odd_nums[] = {1,3,5,7,9};

public OddThread(SyncObject so) {
    t = new Thread(this,"Odd Thread");
    this.so = so;
    t.start();
}

public Thread getThreadInstance() {
    return t;
}

@Override
public void run() {
    while (true) {
        synchronized(so) {
            System.out.println("Odd num is --->" + odd_nums[index]);
            try {
                so.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            index++;
            so.notify();
            if(index>=5) {
                return;
            }
        }
    }
}
}

甚至线程:更新

代码语言:javascript
复制
package com.vipin.multithread.variousdemos;

public class EvenThread implements Runnable {

private Thread t;
int index=0;
SyncObject so=null;

int even_nums[] = {2,4,6,8,10};

public EvenThread(SyncObject so) {
    t = new Thread(this, "Even thread");
    this.so = so;
    t.start();
}

public Thread getThreadInstance() {
    return t;
}

@Override
public void run() {
    while(true) {   
        synchronized(so) {
            System.out.println("Even num is --->" + even_nums[index]);
            so.notify(); <-- Here we are notifying.
            try {
                so.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            index++;
            //so.notify(); <-- commented out.
            if(index>=5) {
                break;
            }
        }
    }
}
}

主要应用:

代码语言:javascript
复制
package com.vipin.multithread.variousdemos;

public class EvenOddDemo {

public static void main(String[] args) throws InterruptedException {
    SyncObject so = new SyncObject();

    OddThread ot = new OddThread(so);
    EvenThread et = new EvenThread(so);

    System.out.println("\nIn main thread");

    Thread.sleep(1000000000);

    System.out.println("Exiting main thread...");
}
}

我使用同步块,并传递类型为==> SyncObject的对象。

SyncObject主要作为参数传递给这些不同的线程。

但是,这个程序会停止,即只执行第一个语句,然后它将永远等待:

这是输出:

奇数是-->1

在主线程中,甚至num是->2。

我无法理解为什么这个程序会永远等待,我使用的对象与我们调用同步()、等待()和通知()的对象相同。根据我的理解,它应该有效,不知道为什么这不起作用。

任何关于这件事为什么要永远等待的线索。

更新:

我在代码中做了一些修改,并进行了更新,并且运行良好。

我还是有些怀疑。即使线程没有锁定监视器,也会被线程调用(),就像在我更新代码之后一样。

事件顺序:

奇数线程首先执行,然后调用wait() <--它释放监视器,现在处于睡眠模式。

甚至线程运行,打印msg,并调用通知() <--这里我没有明确的理解。

甚至当线程调用通知()时,此时它有监视器,所以当它调用通知()时,是否仍然是监视器的所有者?

现在,在偶发线程调用通知()之后,Odd线程就会得到通知,因此它从休眠点开始执行。它正在执行某些操作,并调用notify(),在这一点上,我假定Odd线程没有拥有监视器,它调用通知()。因此,我的问题是,通知()是否工作相同,线程是否拥有监视器?

只有当一个人做代码时,才能真正理解这一点。我读了一本书,我觉得我什么都明白了,似乎我又回到了原点!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-09 15:22:17

这里的问题很简单,这两个线程直接进入等待。线程1获得so,然后打印值等待。线程2然后获得so,打印值然后等待。所以两个人都在睡觉,因为没有人通知他们。因此,一个简单的解决方法是在so.notify()之前执行so.wait()。那他们就不会无止境地等待。

编辑

奇数线程启动,执行&然后等待。然后,甚至线程也会启动、执行、通知&然后等待。甚至连线程都把锁放在监视器上,直到它进入等待状态。

当偶数线程调用通知时,奇怪的线程会唤醒&轮询锁。一旦偶数线程进入等待(&释放锁),那么奇数线程就可以获得锁。

如果偶数线程没有调用通知,那么奇怪的线程将继续休眠。即使是线程也会去等待&释放锁。没有线程正在轮询或试图获取锁,因此程序仍处于挂起状态。

文档还提供了类似的解释。我希望这能消除你的疑虑。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30141414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档