class ThreadB extends Thread{
int total = 0;
public void run(){
synchronized(this){
System.out.println("ThreadB is running...");
for(int i=0;i<100;i++){
total += i;
System.out.println("total is "+total);
}
notify();
//这句的意思是不是假如A线程放弃了锁,B线程得到锁,执行run()方法,
//执行完毕后再唤起A线程?(2)
}
}
}
public class ThreadA{
public static void main(String args[]){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
System.out.println("Waiting for b to complete...");
try{
b.wait();  
         //主线程先获得了对象锁,执行到这儿时,表示当前线程释放该对象锁,是不是?
//用b.wait(); 字面意思好难理解啊...(1)
}catch(InterruptedException e){}      
System.out.println("Completed.Now back to main thread");
//上面的语句,当(2)处没写notify()的时候,主线程没被唤醒怎么执行后面的语句的?
//(3)
}
System.out.println("....Total is:"+b.total);
}
}各位网友,如题,学习中,帮指点下子感谢

解决方案 »

  1.   

    ait()、notify()与notifyAll()是由 Object所提供的方法,您在定义自己的类时会继承下来(记得Java中所有的对象最顶层都继承自Object),wait()、notify()与 notifyAll()都被声明为"final",所以您无法重写它们,透过这三个方法您可以控制线程是否为Runnable状态。您必须在同步化的方法或区块中调用wait()方法,当对象的wait()方法被调用,目前的线程会被放入对象的「等待集合」(Wait set)中,线程会释放对象的锁定,其它的线程可以竞争锁定,取得锁定的线程可以执行同步化区块;被放在等待集中的线程将不参与线程的排班,wait()可以指定等待的时间,如果指定时间的话,则时间到之后线程会再度加入排班,如果指定时间0或不指定,则线程会持续等待,直到有被中断(interrupt)或是被告知(notify)可以参与排班。当对象的notify()被调用,它会从对象的等待集中选出「一个」线程加入排班,被选出的线程是随机的,被选出的线程会与其它正在执行的线程共同竞争对对象的锁定;如果您调用notifyAll(),则「所有」在等待集中的线程都会被唤醒,这些线程会与其它正在执行的线程共同竞争对对象的锁定。简单的说,当线程调用到对象的wait()方法时,表示它要先让出对象的被同步区使用权并等待通知,或是等待一段指定的时间,直到被通知或时间到时再从等待点开始执行,这就好比您要叫某人作事,作到一半时某人叫您等候通知(或等候1分钟之类的),当您被通知(或时间到时)某人会继承为您服务。
      

  2.   

    sleep()自己醒,wait()需要别人叫才能醒
      

  3.   

                //这句的意思是不是假如A线程放弃了锁,B线程得到锁,执行run()方法,
                //执行完毕后再唤起A线程?(2)【答】不是, 是唤醒其他正在等待 “this”(就是当前这个对象)的其他线程,你们可以开始竞争这把锁了。
                    b.wait();  
                     //主线程先获得了对象锁,执行到这儿时,表示当前线程释放该对象锁,是不是?【答】不是, b.wait(),是说我现在开始wait b了,直到其他线程执行了b.notify(),我就开始竞争b这把锁,如果抢到了就,我就执行  (注:你这个case,就这个线程wait   b,  所以只有其他线程b.notify()了,就可以执行)
    所以,b.wait(); 你应该理解成 wait b.
                //上面的语句,当(2)处没写notify()的时候,主线程没被唤醒怎么执行后面的语句的?
                //(3)
    【答】没有办法执行。
      

  4.   

    sleep()自己醒  不完全对,sleep(0)自己是醒不了的,必须别人唤醒。
      

  5.   


    class ThreadB extends Thread{
    int total = 0;
    public void run(){
    synchronized(this){
    System.out.println("ThreadB is running...");
    for(int i=0;i<100;i++){
    total += i;
    System.out.println("total is "+total);
    }
    //notify();注销掉。为什么还能唤醒主线程,主线程还能继续执行?
    }
    }
    }
    public class ThreadA{
    public static void main(String args[]){
    ThreadB b = new ThreadB();
    b.start();
    synchronized(b){
    System.out.println("Waiting for b to complete...");
    try{
    b.wait();  
    }catch(InterruptedException e){}      
    System.out.println("Completed.Now back to main thread");
    }
    System.out.println("....Total is:"+b.total);
    }
    }
    //两只熊猫,过来看一下,没明白。
      

  6.   

      //notify();注销掉。为什么还能唤醒主线程,主线程还能继续执行?
    【答】因为ThreadB 可以无限制的执行完毕,这样锁就自动释放了,当然主线程可以执行。
    只是如果你notify一下,主线程可以更加及时的继续执行。
    对不起,没有及时的关注此贴。
      

  7.   

    notify();注销掉。为什么还能唤醒主线程,主线程还能继续执行?
    因为synchronized块运行完了,然后就释放对象锁了,主线程中的synchronized又得到了对象锁,所以主线程再次运行。关键还是对对象锁理解因为synchronized的作用就是获得对象锁。在没有使用wait()与notify()的情况下,当运行完synchronized的方法或块时,就释放了对象锁。synchronized锁定的都是同一个对象,即b
    b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机会执行
      

  8.   

    notify();注销掉。为什么还能唤醒主线程,主线程还能继续执行?
    因为synchronized块运行完了,然后就释放对象锁了,主线程中的synchronized又得到了对象锁,所以主线程再次运行。关键还是对对象锁理解因为synchronized的作用就是获得对象锁。在没有使用wait()与notify()的情况下,当运行完synchronized的方法或块时,就释放了对象锁。synchronized锁定的都是同一个对象,即b
    b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机会执行
      

  9.   

    notify();注销掉。为什么还能唤醒主线程,主线程还能继续执行?
    因为synchronized块运行完了,然后就释放对象锁了,主线程中的synchronized又得到了对象锁,所以主线程再次运行。关键还是对对象锁理解因为synchronized的作用就是获得对象锁。在没有使用wait()与notify()的情况下,当运行完synchronized的方法或块时,就释放了对象锁。synchronized锁定的都是同一个对象,即b
    b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机会执行