1、notify与notifyAll的具体区别是啥?notify是随机选择一个线程来唤醒它,其他的还是处于WAITING状态,notifyAll()唤醒所有等待该对象监视锁的线程,让它们去竞争该对象的锁。对于这两种方式,最终都是一个线程获得监视锁,但是具体实现上有什么不同呢?有什么情况是用notify优于使用notifyAll的?2、所谓的spurious wakeup是指什么?有没有例子说明一下?3、这点是关于一个由于调用对象的wait方法进入WAITING状态的线程,最后被唤醒又再可以被CPU调度时(不管是因为什么变为可以被CPU调度的)所发生的事:这个线程被从wait set中移除,又去和其他线程抢夺监视锁,获得锁后恢复现场(不知道这里说恢复现场对不对?)我想知道所谓获得锁是什么意思?就是获得了一块内存吗?4、wait函数是什么时候返回的?是调用wait后马上返回还是再这个线程再次获得监视锁后返回,然后又对while的条件进行检测(我觉得是后者)5、notify和notifyAll也会释放锁吧?会不会有那种场景:那个调用notify(或notifyAll)后,紧接着这个语句后面还执行其他语句?比如:notify(); other_statement;

解决方案 »

  1.   

    1.假如三个线程A、B、C,
    synchronized(obj)
    {
            obj.wait();//某种情况A不执行wait
            xxxx//处理之后,导致A能够notify,B和C不能
    }
    然后可能某时B C都wait后,A进入,A如果只notify一个,你会发现B醒了继续执行结束,但是C一直wait没法醒
    此时用notifyAll就会让B和C等在资源上而不是wait等人唤醒
    2.不清楚
    3.锁就相当于资源,比如上面的obj那个,假如就一把锁,你获得了锁,把仓库(块)锁上了进入了仓库(块执行),别人此时没锁的钥匙就没法进入,你出仓库把锁给别人,别人再锁上等等
    4.notify和notifyAll才能让wait返回
    5.notify和notifyAll只会唤醒在wait的线程,不会释放锁
      

  2.   

    第二哥问题我也想知道,百度了一下 无奈此人 错别字太多,我意淫能力不够啊。http://blog.csdn.net/turkeyzhou/article/details/5775301
      

  3.   

    昨天我倒是谷歌搜到了但是不知道是不是正确的 
    http://tieba.baidu.com/f?kz=702270551
    你如果不是想进百度。。其实可以不用百度搜技术的东西
      

  4.   

    1
    把synchronized比作一扇门,把wait队列比作一个休息室,那么notify就是在休息室随机通知某个人,把门钥匙给他(看谁顺眼给谁),其他人继续在休息室等待。而notifyAll就是通知所有人,然后把钥匙抛出去,让所有人抢,此时,休息室的人就不会再安分地呆在休息室等待了,而是会挤在门前等待强钥匙。
    所以区别就是,nofity的时候,其他人还在等待室,notifyAll的时候,其他人挤在门前2
    spurious wakeup就是虚假唤醒,比如1中,notifyAll的时候,所有人都挤在门前了,但是有些人是不符合条件的,应该继续等待,所以就算他们挤在门前了,也要管理员检查一下他们的身份,不符合的继续赶到休息室里去。这样的唤醒就是虚假的唤醒。在程序中,一般用while循环来做
    while(condition) {
        wait(); //即使线程被唤醒了,执行while检查,发现还是满足等待条件,就让线程继续等待
    }3
    线程进入等待队列的时候,线程的进入等待队列前的信息都被压栈,所谓的恢复现场,就是线程信息出栈,让线程恢复进入等待前的状态。获得锁就是获得对象的控制权限,系统有个对象的monitor,要想控制对象,就要从monitor中获得权限,比如你要进一个门,就要找管理员拿钥匙。从内存的角度来说,可以理解为获得一块内存的访问权,从实现的角度来说,也许只是在monitor设置一个flag(就看底层怎么实现锁管理),就好像在管理处登个记。4
    你所说的返回是什么意思?如果说是wait方法本身的返回,那么程序会在wait处发生等待,直到notify或notifyAll以后才返回继续执行后面的代码。如果说是程序的返回,那么就是把线程当前的状态压栈,然后把线程放到等待队列,然后程序指针就转到其他地方去执行了(因为CPU放弃让线程继续使用)。5
    notify和notifyAll只是唤醒其他等待中的线程,释放不释放锁,就要看代码是否退出synchronized块,也就是说某个人上厕所,他喊一声拉完了,这样其他等待的人就知道了,但是那个人还没离开厕所,还在占用着,其他人也只能在门口等待,直道那个人离开厕所,即离开synchronized块
      

  5.   

    谢谢阿宝~~~在第一问那里,一般都建议用notifyAll唤醒所有在该对象wait set中的线程,让它们自己去抢,有没有什么情况下是用notify会比较好的?
      

  6.   

    这个就看具体需求了,用多个锁的例子一般采用notify比较好。
    比如A线程组执行任务1,B线程组执行任务2,任务2依赖任务1,那么A线程组做好任务1准备条件后,只需要唤醒B线程组中任意一个线程就可以了,这时候可以不用把B线程组全部唤醒。不过这样的处理需要协调好,否则没有被notify的线程就会一直wait,导致程序可能停止而无法结束,所以一般在结束条件处都会notifyAll来唤醒所有的线程。