程序如下:
class Reader extends Thread {
    Calculator c;    public Reader(Calculator calc) {
        c = calc;
    }    public void run() {
        synchronized (c) {
            try {
                System.out.println("Waiting for calculation ..." + " run by:" +
                                   Thread.currentThread().getName());
                c.wait();
            } catch (InterruptedException e) {}
        }
        System.out.println("Total id : " + c.total + " run by:" +
                           Thread.currentThread().getName());
    }    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        Reader r1 = new Reader(calculator);
        r1.setName("Reader1");
        r1.start();
        Reader r2 = new Reader(calculator);
        r2.setName("Reader2");
        r2.start();
        Reader r3 = new Reader(calculator);
        r3.setName("Reader3");
        r3.start();
        
        try{
            Thread.sleep(1000);
        }catch(Exception e){
        }
        
        calculator.run();              //(*)
        //calculator.start();
       
    }
}
class Calculator extends Thread {
    int total;    public void run() {        synchronized (this) {
            for (int i = 0; i < 100; i++) {
                total += i;
            }
            notify();                        //(@)
            //notifyAll();
        }
        
    }}//---------------------------------------------------------------
(*) 处如果调用:calculator.run(); 则可以得到我想要的结果:
1 (@) 处调用notify();时一个线程被唤醒 
  输出:
Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3Total id : 4950 run by:Reader12 (@) 处调用notifyAll()时三个线程都被唤醒 
输出:
Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3Total id : 4950 run by:Reader1Total id : 4950 run by:Reader2
3 (@) 处既不调用notify()也不调用notifyAll时三个线程都被阻塞
输出:
Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3
Total id : 4950 run by:Reader3但是,当 (*) 处调用:calculator.start()时,令我不解的是,此时无论
(@)处调用notify还是调用notifyAll,还是既不调用notify也不调用notifyAll,
都输出:
Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3Total id : 4950 run by:Reader1Total id : 4950 run by:Reader2Total id : 4950 run by:Reader3此时三个线程都被唤醒了,为什么? 请高手指点!

解决方案 »

  1.   

    刚才发的有点小错,重新发一下程序如下:
    class Reader extends Thread {
        Calculator c;    public Reader(Calculator calc) {
            c = calc;
        }    public void run() {
            synchronized (c) {
                try {
                    System.out.println("Waiting for calculation ..." + " run by:" +
                                       Thread.currentThread().getName());
                    c.wait();
                } catch (InterruptedException e) {}
            }
            System.out.println("Total id : " + c.total + " run by:" +
                               Thread.currentThread().getName());
        }    public static void main(String[] args) {
            Calculator calculator = new Calculator();
            Reader r1 = new Reader(calculator);
            r1.setName("Reader1");
            r1.start();
            Reader r2 = new Reader(calculator);
            r2.setName("Reader2");
            r2.start();
            Reader r3 = new Reader(calculator);
            r3.setName("Reader3");
            r3.start();
            
            try{
                Thread.sleep(1000);
            }catch(Exception e){
            }
            
            calculator.run();              //(*)
            //calculator.start();
           
        }
    }
    class Calculator extends Thread {
        int total;    public void run() {        synchronized (this) {
                for (int i = 0; i < 100; i++) {
                    total += i;
                }
                notify();                        //(@)
                //notifyAll();
            }
            
        }}//---------------------------------------------------------------
    (*) 处如果调用:calculator.run(); 则可以得到我想要的结果:
    1 (@) 处调用notify();时一个线程被唤醒 
      输出:
    Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3Total id : 4950 run by:Reader12 (@) 处调用notifyAll()时三个线程都被唤醒 
    输出:
    Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3Total id : 4950 run by:Reader1Total id : 4950 run by:Reader2Total id : 4950 run by:Reader33 (@) 处既不调用notify()也不调用notifyAll时三个线程都被阻塞
    输出:
    Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3
    但是,当 (*) 处调用:calculator.start()时,令我不解的是,此时无论
    (@)处调用notify还是调用notifyAll,还是既不调用notify也不调用notifyAll,
    都输出:
    Waiting for calculation ... run by:Reader1Waiting for calculation ... run by:Reader2Waiting for calculation ... run by:Reader3Total id : 4950 run by:Reader1Total id : 4950 run by:Reader2Total id : 4950 run by:Reader3此时三个线程都被唤醒了,为什么? 请高手指点!
      

  2.   

    c.wait();使得r1,r2,r3三个线程都同时在等待,当执行到run()方法后,自然会唤醒!
      

  3.   

    我的问题是如果在main中调calculator.run();三个线程不会自然唤醒,必须显示调用notify
    或者notifyAll才能唤醒;如果调用calculator.start(),则三个线程自动唤醒(不用调用notify
    或者notifyAll),这是什么原因 ?