前面的学习学过,为了多线程之间的同步,有wait( )和notify( )两个方法使用,不过这两个方法是在Object类上的,也就是所有的对象实体都有这两个方法。回顾一下,调用wait( )方法后,线程会在这个对象的等待队列上等待,直到其他线程调用notify( )方法,notify( )方法会在等待队列上随机唤醒一个等待线程,注意它是随机的!!随机唤醒!!
对象的wait( )和notify( )方法的调用都必须包含在对应的synchronized语句里,就像这样:
也就是先获得这个对象的监视器。
这是对象上的方法,对于重入锁,它也有线程等待和线程唤醒两个方法,那就是重入锁对象里的await( )方法和signal( )方法,具体怎么用?看看下面这段代码:
在第6行我们通过重入锁的方法newCondition( )绑定一个Condition实例和一个重入锁,也就是lock和condition绑定,然后就可以调用condition的await( )方法让线程在合适的时候等待,我们注意看代码第11到13行,在调用await( )方法时,必须先拿到这个condition实例绑定的锁,也就是必须先执行重入锁的lock( )方法,在获得与condition绑定的对应的锁后,再执行await( )方法,线程进入等待状态并释放掉重入锁lock。线程等待后对应的唤醒方法是signal( ),signal( )方法和notify( )方法类似,都是从等待队列中随机唤醒一个线程,注意是随机唤醒!!signal( )方法调用前同样要先获得与之绑定的重入锁,看第26行,在signal( )方法被调用后,唤醒一个线程,必须也释放掉这个重入锁,因为被唤醒的线程会先去申请重入锁,成功后线程才会继续执行,如果我们把代码第28行的unlock调用拿走,看看会发生什么事情?
虽然线程T1被唤醒了,但是T1的下一步是先去申请重入锁,由于锁一直被condition占用没有被释放,所以T1一直等待锁,并没有真正往下执行。