我试图实现这个目的:创建两个不同的线程,一个打印奇数,一个打印偶数。一旦一个线程打印一个数字,它就必须等待另一个线程,依此类推,即一个接一个。
为实现这一点,我使用synchronized块以及wait()和notify()。
我正在创建一个类,其对象将用于传递给两个线程中的synchronized块。
- >这是将被传递给synchronized块的used对象。
package com.vipin.multithread.variousdemos;
public class SyncObject {
public SyncObject () {
}
}
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;
}
}
}
}
}
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;
}
}
}
}
}
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...");
}
}
---&GT;如代码所示,我创建两个线程来打印偶数和奇数。我正在使用synchronized块,并传递类型==&gt;的对象SyncObject。
SyncObject我作为参数传递给main中的这些不同线程。
然而,这个程序停止了,即只停留第一个语句,然后它永远等待:
奇数是---> 1
在主线程中 偶数是---> 2
我无法理解为什么这个程序会等待,我正在使用我们正在调用synchronized(),wait()和notify()的SAME对象。根据我的理解,它应该工作,不知道为什么这不起作用。
关于为什么这是永远等待的任何线索。
我在代码中做了一些更改,UPDATE并且工作正常。
我还有一些疑问。即使没有锁定监视器,线程也会调用notify(),就像我更新代码后的情况一样。
事件顺序:
首先执行奇数线程,然后调用wait()&lt; - 它释放监视器,现在处于睡眠模式。
甚至线程运行,打印msg,并调用notify()&lt; - 这里我没有清楚的理解。
当Even调用notify()时,那时它有监视器,所以当它调用notify()时,是否仍然拥有监视器?
现在,在Even调用notify()之后,奇数线程得到通知,因此它从正在休眠的点开始执行。它正在做一些执行并调用notify(),在那一点上我认为奇数线程不拥有监视器,它调用notify()。所以,我的问题是,无论线程是否拥有监视器,notify()的工作方式是否相同?
只有当人们执行代码时,才能真正理解这一点。我读了书,我觉得我理解了一切,似乎我又回到了原点!
答案 0 :(得分:2)
这里的问题只是两个线程直接进入等待状态。线程1获得so
,打印值然后等待。线程2然后得到so
,打印值然后等待。所以两个人都在睡觉,因为没有人在那里通知他们。因此,一个简单的解决方法就是在so.notify()
之前进行so.wait()
。然后他们没有无限期待。
修改强>
奇数线程开始,执行&amp;然后等待。然后甚至线程启动,执行,通知&amp;然后等待。甚至线程都会锁定监视器,直到它进入等待状态。
当偶数线程调用通知时,奇数线程唤醒&amp;民意调查锁定。一旦偶数线程进入等待(并释放锁定),则奇数线程可以获得锁定。
如果偶数线程没有调用notify,则奇数线程将继续休眠。偶数线程将等待&amp;释放了锁。没有线程轮询或尝试获取锁,因此程序保持挂起状态。
documentation也提供了类似的解释。我希望能够解除你的疑虑。