我试图做到这一点:创建两个不同的线程,一个打印奇数,一个打印偶数。一旦一个线程打印了一个数字,它就必须等待另一个线程,以此类推。
为了实现这一点,我使用了同步块以及等待()和通知()。
我正在创建一个类,它的对象将被用来传递给两个线程中的同步块。
以下是代码:
->这是使用的对象,它将被传递给同步块。
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...");
}
}我使用同步块,并传递类型为==> SyncObject的对象。
SyncObject主要作为参数传递给这些不同的线程。
但是,这个程序会停止,即只执行第一个语句,然后它将永远等待:
这是输出:
奇数是-->1
在主线程中,甚至num是->2。
我无法理解为什么这个程序会永远等待,我使用的对象与我们调用同步()、等待()和通知()的对象相同。根据我的理解,它应该有效,不知道为什么这不起作用。
任何关于这件事为什么要永远等待的线索。
更新:
我在代码中做了一些修改,并进行了更新,并且运行良好。
我还是有些怀疑。即使线程没有锁定监视器,也会被线程调用(),就像在我更新代码之后一样。
事件顺序:
奇数线程首先执行,然后调用wait() <--它释放监视器,现在处于睡眠模式。
甚至线程运行,打印msg,并调用通知() <--这里我没有明确的理解。
甚至当线程调用通知()时,此时它有监视器,所以当它调用通知()时,是否仍然是监视器的所有者?
现在,在偶发线程调用通知()之后,Odd线程就会得到通知,因此它从休眠点开始执行。它正在执行某些操作,并调用notify(),在这一点上,我假定Odd线程没有拥有监视器,它调用通知()。因此,我的问题是,通知()是否工作相同,线程是否拥有监视器?
只有当一个人做代码时,才能真正理解这一点。我读了一本书,我觉得我什么都明白了,似乎我又回到了原点!
发布于 2015-05-09 15:22:17
这里的问题很简单,这两个线程直接进入等待。线程1获得so,然后打印值等待。线程2然后获得so,打印值然后等待。所以两个人都在睡觉,因为没有人通知他们。因此,一个简单的解决方法是在so.notify()之前执行so.wait()。那他们就不会无止境地等待。
编辑
奇数线程启动,执行&然后等待。然后,甚至线程也会启动、执行、通知&然后等待。甚至连线程都把锁放在监视器上,直到它进入等待状态。
当偶数线程调用通知时,奇怪的线程会唤醒&轮询锁。一旦偶数线程进入等待(&释放锁),那么奇数线程就可以获得锁。
如果偶数线程没有调用通知,那么奇怪的线程将继续休眠。即使是线程也会去等待&释放锁。没有线程正在轮询或试图获取锁,因此程序仍处于挂起状态。
文档还提供了类似的解释。我希望这能消除你的疑虑。
https://stackoverflow.com/questions/30141414
复制相似问题