面试题答案
一键面试对锁的处理
- wait():调用
wait()
方法时,线程会释放它当前持有的对象锁。这意味着其他线程可以获取该锁并访问被同步的代码块或方法。例如在一个生产者 - 消费者模型中,当生产者发现缓冲区已满时调用wait()
,释放锁,使得消费者线程有机会获取锁并从缓冲区消费数据。 - sleep():线程调用
sleep()
方法时,不会释放它所持有的任何锁。即使线程进入睡眠状态,它依然保持对锁的占有,其他线程无法获取该锁访问被同步的区域。比如在一个同步方法中调用sleep()
,其他线程在该线程睡眠期间无法进入该同步方法。
唤醒机制
- wait():必须通过其他线程调用同一对象的
notify()
或notifyAll()
方法来唤醒等待的线程。notify()
随机唤醒一个等待在该对象上的线程,而notifyAll()
则唤醒所有等待在该对象上的线程。例如在生产者 - 消费者场景中,消费者从缓冲区取出数据后调用notify()
通知等待的生产者线程可以继续生产。 - sleep():在指定的睡眠时间结束后,线程会自动唤醒进入就绪状态,不需要其他线程的干预。例如设置
Thread.sleep(1000)
,线程睡眠1秒后会自动醒来准备竞争CPU资源。
应用场景
- wait():常用于多线程间的协作场景,如生产者 - 消费者模型、线程池的资源分配等。通过线程间的等待和唤醒机制来协调任务的执行顺序和资源的合理利用。比如在数据库连接池实现中,当没有可用连接时,获取连接的线程调用
wait()
等待,当有连接被释放时,通过notify()
唤醒等待线程。 - sleep():主要用于让线程暂停执行一段时间,以满足特定的时间控制需求。例如定时任务执行、模拟网络延迟等场景。如在一个游戏开发中,为了实现动画的流畅过渡,可能会使用
Thread.sleep()
来控制每一帧的显示时间间隔。