程序停止:wait()和notify() [英] Program gets halted: wait() and notify()

查看:148
本文介绍了程序停止:wait()和notify()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现这个目的:创建两个不同的线程,一个打印奇数,一个打印偶数。一旦一个线程打印一个数字,它就必须等待另一个线程,依此类推,即一个接一个。

I am trying to achieve this: Created two different threads, one prints odd numbers, one prints even numbers. Once one thread prints a number, it has to wait for the other thread and so on, that is one-after-other.

为实现这一点,我使用的是同步阻塞以及wait()和notify()。

To achieve this, i am using synchronized block along with wait() and notify().

我正在创建一个类,其对象将用于传递给两个线程中的synchronized块。

I am creating a class whose's object will be used to pass to synchronized block in both the threads.

- >这是用于传递给synchronized块的对象。

--> This is used object which will be passed to synchronized block.

package com.vipin.multithread.variousdemos;

    public class SyncObject {

        public SyncObject () {  

        }
}



奇数线程:



Odd Thread:

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;
            }
        }
    }
}
}



偶数线程:UPDATE



Even Thread: UPDATE

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;
            }
        }
    }
}
}



主要应用程序:



Main Application:

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...");
}
}

--->如代码所示,我我正在创建两个线程来打印偶数和奇数。我正在使用synchronized块,并传递类型==> SyncObject的对象。

---> As seen in the code, I am creating two threads to print even and odd numbers. I am using synchronized block, and passing object of type ==> SyncObject.

SyncObject我作为参数传递给main中的这些不同线程。

SyncObject I am passing as argument to these different threads in main.

然而,这个程序停止,即只停留第一个语句执行,然后它永远等待:

However, this programs halts, i.e stuck only first statement gets executed, and then it waits forever:

奇数是---> 1

在主线程中
偶数num是--- > 2

In main thread Even num is --->2

我无法理解为什么这个程序会等待,我正在使用我们正在调用synchronized(),wait()和notify的SAME对象( )。根据我的理解,它应该工作,不知道为什么这不起作用。

I am not able to understand why this program waits for ever, I am using SAME object on which we are invoking synchronized(), wait() and notify(). As per my understanding, it should work, not sure why this is not working.

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

Any clues as to why this is waiting forever.

我在代码中做了一些更改,UPDATE并且工作正常。

I did some changes in the code, UPDATE and it works fine.

我还有一些疑问。即使没有锁定监视器,也会被线程调用notify(),就像我更新代码后的情况一样。

I still have some doubt. Does notify() be called by the thread even if it has not locked the monitor, like in my case after i updated the code.

事件顺序:

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

Odd thread gets executed first, then it calls wait() <-- it releases the monitor and now in sleep mode.

甚至线程运行,打印msg,并调用notify()< - 这里我没有清楚的理解。

Even thread runs, prints msg, and calls notify() <-- here i am not having clear understanding.

当Even调用notify()时,那时它有监视器,所以当它调用notify()时,是否仍然拥有监视器?

When Even thread calls notify(), at that point it has the monitor, so when it calls notify(), does is still own the monitor?

现在,在Even调用notify()之后,然后是Odd线程得到通知,因此它从它正在睡觉的点开始执行。它正在做一些执行并调用notify(),在那一点上,我认为Odd线程不拥有监视器,它调用notify()。所以,我的问题是,无论线程是否拥有监视器,notify()的工作方式是否相同?

Now, after Even thread calls notify(), then Odd thread gets notified, and hence it starts execution from the point it was sleeping. It is doing some execution and calls notify(), at that points I presume Odd thread is NOT owning the monitor, it calls notify(). So, my question is, does notify() work same whether or not the thread owns the monitor?

只有当一个人执行代码时,才能真正理解这一点。我读了书,我觉得我理解了一切,似乎我又回到了原点!

It is only when one do the code, one really understands this. I read book and i felt i understood everything, and seems i am back to square one!

推荐答案

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

The problem here is simply that both threads go straight into wait. Thread 1 gets so, prints value then waits. Thread 2 then gets so, prints value then waits. So both are sleeping away, since nobody is there to notify them. So, a simple fix would be to do so.notify(), right before so.wait(). Then they're not infinitely waiting.

编辑

奇数线程启动,执行&然后等待。然后甚至线程启动,执行,通知&然后等待。甚至线程都会锁定显示器,直到它进入等待状态。

Odd thread starts, executes & then waits. Then even thread starts, executes, notifies & then waits. Even thread holds the lock over the monitor until it goes into wait.

当偶数线程调用通知时,奇数线程唤醒&民意调查锁定。一旦偶数线程进入等待(并释放锁定),则奇数线程可以获得锁定。

When the even thread called on notify, the odd thread awakens & polls for the lock. Once the even thread goes into wait (& releases the lock), then the odd thread can obtain the lock.

如果偶数线程没有调用notify,那么奇数线程将继续休眠。偶数线程将等待&释放了锁。没有线程轮询或尝试获取锁定,因此程序保持挂起状态。

If the even thread had not called on notify, then the odd thread would continue to sleep. The even thread would have gone to wait & released the lock. No thread is polling or attempting to obtain the lock, hence the program remains in the suspended state.

文档也提供了类似的解释。我希望能够解除你的疑虑。

The documentation also provides a similar explanation. I hope that clears your doubts.

这篇关于程序停止:wait()和notify()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆