JVM中每个对象都会有一个监视器(monitor对象),它随着对象一起创建和销毁,监视器的作用便是保护临界区的代码是互斥运行的。重量级锁,wait()方法,notify()方法都是基于它来实现的
wait()方法底层原理
当线程调用锁对象的wait()方法后,JVM会把当前线程加入锁对象对应的监视器阻塞队列当中,然后释放监视器的owner字段,使得其他线程可以抢夺当前锁对象的监视器
notify()底层原理
当线程调用了某个锁对象的notify()方法后,JVM会随机将其监视器阻塞队列中的一条线程移入就绪队列,处于就绪队列中的线程需要重新抢夺监视器的所有权,也就是owner字段,当线程获得了监视器的所有权后便可以重新执行
为什么这两个方法需要结合synchronized使用
wait()方法与notity()方法底层都与监视器有关,如果连锁对象都不存在,那么这两个方法就没有意义了
wait()方法与sleep()方法的区别与相同点
区别
sleep方法是Thread类的一个静态方法,使当前线程睡眠n毫秒,进入阻塞状态,睡眠期间并不释放锁
wait方法是Object类的方法,它的底层会把当前线程加入锁对象对应的监视器阻塞队列当中,然后释放监视器的owner字段,使得其他线程可以抢夺当前锁对象的监视器,由于需要对应锁对象的监视器,所以必须与synchronized关键字一起使用。阻塞时会释放锁,相比于sleep方法,wait方法执行后线程不对自动苏醒,需要调用notify方法或notifyAll方法,并且wait方法通常用于线程间通信,而sleep方法用于暂停线程
相同点
都可以使线程进入阻塞状态