首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

关于notifyAll()的唤醒顺序跟程序执行结果,求教了

2013-07-01 
关于notifyAll()的唤醒顺序和程序执行结果,求教了本帖最后由 cloudeagle_bupt 于 2013-06-06 17:51:35 编

关于notifyAll()的唤醒顺序和程序执行结果,求教了
本帖最后由 cloudeagle_bupt 于 2013-06-06 17:51:35 编辑


package slot;

public class ThreadPriority {

/**
 * @param args
 */
public static void main(String[] args) {

Slot s = new Slot();

// TODO Auto-generated method stub
        for(int i=1; i<6 ;i++)
        {
        Consumer cr = new Consumer(s) ;
        cr.setPriority(i);
        cr.start();
        }
        
        Producer p = new Producer(s);
        p.start();
}

}

class Slot {
public int slotNum = 0;

public synchronized void produce() {
slotNum++;
}

public synchronized void consume() {
slotNum--;
}
}

class Producer extends Thread {

Slot slot;

public Producer(Slot s) {
slot = s;
}

public void run() {
try {
synchronized (slot) {
while (slot.slotNum == 20)
slot.wait();


slot.produce();
slot.notifyAll();
System.out.println("Thread " + this.getName() + " producing ! slotNum is " + slot.slotNum+"\n");

}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

class Consumer extends Thread {

Slot slot;

public Consumer(Slot s) {
slot = s;
}

public void run() {
try {
synchronized (slot) {
while (slot.slotNum == 0)
slot.wait();

slot.consume();
slot.notifyAll();
System.out.println(" -------------- Thread " + this.getName() + " consuming ! slotNum is " + slot.slotNum+"\n");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


执行结果: 

Thread Thread-5 producing ! slotNum is 1

 -------------- Thread Thread-4 consuming ! slotNum is 0
 
  程序死在这里不动了!

   这里的目的是为了测试notifyAll()函数唤醒睡眠线程时,线程的唤醒是按照优先级还是随机的。
   可是执行结果让我比较困惑, 两个问题:
   1. 为什么会死在那里? 这里应该没有造成死锁吧?
   2. 我尝试了很多次,每次程序的执行结果都是上面那个,consumer5个执行线程,最高的优先级应该是5,可见不是按照优先级的顺序来唤醒的。
   3. 如果想实现按照优先级的顺序将线程唤醒,有什么办法么? notifyAll()和notify()函数都不具备此功能。现实中是有此类需求的,比如说,一个新的资源空闲出来了,需要将其按照优先级给睡眠的线程依次分配,那这种情况下怎么办?
   求教了。
   

分享到:
[解决办法]
这个程序没有错,main方法先它运行5个线程,由于slot.slotNum == 0,均等待,直到
  Producer p = new Producer(s); 
        p.start(); 运行
synchronized (slot) {                 while (slot.slotNum == 20)                     slot.wait();                             slot.produce();             slot.notifyAll();             System.out.println("Thread " + this.getName() + " producing ! slotNum is " + slot.slotNum+"\n");               } 
slot.produce(); 这儿slot.slotNum == 1,
 slot.notifyAll唤醒所有线程,
打印System.out.println("Thread " + this.getName() + " producing ! slotNum is " + slot.slotNum+"\n");该 线程结束,
其中thread4抢到资源,线程4运行完slot.slotNum == 0,其他线程继续等待
最终原因你只生参了一个产品,消费共有五个线程,一个运行晚还有4个。自然是等待
[解决办法]
不建议用优先级。因为有些语言不支持1到10的。notify是随机唤醒的,要想唤醒特定的线程,设置相应的bool值变量。

热点排行