我正在尝试创建两个线程 OddThread 和 EvenThread ,它们分别打印奇数和偶数。我试图同步这两个线程来打印自然数字。
它工作正常,但我不知道为什么它会在一段时间后陷入僵局。
我的代码如下所示:
public class NaturalNoPrint {
public static void main(String[] args) {
Object lock = new Object();
Thread oddThread = new Thread(new OddThread(lock));
Thread evenThread = new Thread(new EvenThread(lock));
oddThread.start();
evenThread.start();
}
}
class OddThread implements Runnable{
private int no=1;
private Object lock;
OddThread(Object lock){
this.lock=lock;
}
public void run(){
while(true){
synchronized(lock){
try {
lock.wait();
System.out.println(no);
no+=2;
lock.notify();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class EvenThread implements Runnable{
private int no=2;
private Object lock;
EvenThread(Object lock){
this.lock=lock;
}
public void run(){
while(true){
synchronized(lock){
try{
lock.notify();
lock.wait();
System.out.println(no);
no+=2;
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}
请帮助确定死锁的原因。
答案 0 :(得分:4)
你有竞争条件。
如果调度程序首先调度EvenThread
,它会在lock
上同步并立即调用notify
,从而释放监视器。然后,OddThread
会获取lock
监视器并调用wait()
来释放监视器但不会notify
EvenThread
。两个线程现在都在等待永远不会来的notify
。
这可能在执行期间的任何时候发生,并且由Thread
调度程序决定。
答案 1 :(得分:1)
以下是死锁的情况:
OddThread: waits
EvenThread: notifies
OddThread: prints, notifies (EvenThread is not waiting yet! - here is the problem)
OddThread: waits
EvenThread: waits
答案 2 :(得分:0)
这是我修改后的信号量代码,工作正常:
public class NaturalNoPrint {
public static void main(String[] args) {
Semaphore oddMutex = new Semaphore(0);
Semaphore evenMutex = new Semaphore(0);
Thread oddThread = new Thread(new OddThread(oddMutex,evenMutex));
Thread evenThread = new Thread(new EvenThread(oddMutex,evenMutex));
evenThread.start();
oddThread.start();
}
}
class OddThread implements Runnable{
private int no=1;
private Semaphore oddMutex,evenMutex;
OddThread(Semaphore oddMutex,Semaphore evenMutex){
this.oddMutex=oddMutex;
this.evenMutex=evenMutex;
}
public void run(){
while(true){
//synchronized(lock){
try {
//lock.wait();
oddMutex.acquire();
System.out.println(no);
no+=2;
Thread.sleep(1000);
//lock.notify();
evenMutex.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
//}
}
}
}
class EvenThread implements Runnable{
private int no=2;
//private Object lock;
private Semaphore oddMutex,evenMutex;
EvenThread(Semaphore oddMutex,Semaphore evenMutex){
this.oddMutex=oddMutex;
this.evenMutex=evenMutex;
}
public void run(){
while(true){
//synchronized(lock){
try{
//lock.notify();
//lock.wait();
oddMutex.release();
evenMutex.acquire();
System.out.println(no);
no+=2;
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
//}
}
}
}
感谢 Sotirios Delimanolis 和其他成员帮助我找出根本原因..