interview
java-concurrency
Java中的wait、notify和notifyAll方法有什么作用?

Java并发面试题, Java 中的 wait,notify 和 notifyAll 方法有什么作用?

Java并发面试题, Java 中的 wait,notify 和 notifyAll 方法有什么作用?

QA

Step 1

Q:: Java 中的 wait 方法有什么作用?

A:: 在 Java 中,wait 方法是 Object 类的一部分,它使调用该方法的线程进入等待状态,直到另一个线程调用同一个对象上的 notify 或 notifyAll 方法。wait 方法通常与 synchronized 代码块一起使用,以确保在多线程环境中对象的状态一致性。wait 使当前线程暂停执行并释放当前持有的锁,允许其他线程获得执行机会。

Step 2

Q:: Java 中的 notify 方法有什么作用?

A:: notify 方法用于唤醒一个正在等待该对象监视器(使用 wait 方法)的线程。如果多个线程在等待同一个对象监视器,notify 方法会随机唤醒其中一个线程。被唤醒的线程必须重新获得该对象的锁,才能继续执行。

Step 3

Q:: Java 中的 notifyAll 方法有什么作用?

A:: notifyAll 方法用于唤醒所有正在等待该对象监视器的线程。被唤醒的线程仍然需要竞争对象的锁,只有一个线程可以成功获得锁并继续执行。notifyAll 常用于确保所有等待线程都能被唤醒,从而避免死锁或线程饿死的情况。

Step 4

Q:: 为什么 wait 和 notify/notifyAll 方法要在 synchronized 块内调用?

A:: 因为 wait、notify 和 notifyAll 方法是依赖于对象监视器的,在调用这些方法时需要持有对象的锁。如果不在 synchronized 块内调用这些方法,会抛出 IllegalMonitorStateException 异常。synchronized 块确保只有一个线程能持有对象的锁,从而避免多个线程同时调用 wait 或 notify 方法时引发竞态条件或数据不一致的问题。

Step 5

Q:: 什么是线程间通信?为什么需要线程间通信?

A:: 线程间通信是指多个线程之间通过共享变量或等待/通知机制来交换信息或协调工作。线程间通信在多线程编程中非常重要,因为它允许多个线程协同工作以完成复杂任务,例如生产者-消费者模式。线程间通信有助于提高程序的并发性和效率,确保数据的一致性和正确性。

用途

面试中问到这些问题是因为在实际的生产环境中,Java 开发者经常需要编写多线程程序来提高系统的性能和响应速度。尤其是在高并发场景下,如处理海量数据、构建高性能服务器、实时数据处理等场景,线程的同步和通信变得非常重要。开发者必须理解和正确使用 wait、notify 和 notifyAll 方法,以避免死锁、数据不一致以及其他并发问题,从而确保系统的稳定性和可靠性。\n

相关问题

🦆
什么是线程安全?如何确保线程安全?

线程安全是指多个线程并发访问共享资源时,不会破坏数据的一致性或导致程序的异常行为。确保线程安全的常见方法包括使用 synchronized 关键字、锁(如 ReentrantLock)、原子变量(如 AtomicInteger)以及无锁数据结构。

🦆
什么是死锁?如何避免死锁?

死锁是指两个或多个线程在相互等待对方持有的资源时进入无限等待状态,从而导致程序无法继续执行。避免死锁的方法包括:通过正确的锁顺序避免循环依赖、使用 tryLock 方法设置超时、减少锁的持有时间、或者通过锁分解和锁合并来减少并发冲突。

🦆
什么是线程池?如何使用线程池?

线程池是一个管理和复用线程的机制,用于限制并控制同时执行的线程数量,避免因线程数量过多导致的系统资源耗尽。Java 中可以通过 Executors 提供的工厂方法创建不同类型的线程池,如 FixedThreadPool、CachedThreadPool 和 ScheduledThreadPool。使用线程池可以提高系统性能,减少线程创建和销毁的开销。

🦆
什么是可重入锁?与 synchronized 的区别是什么?

可重入锁(ReentrantLock)是一个独立的锁实现,允许线程在持有锁时再次获取锁而不会发生死锁。与 synchronized 相比,ReentrantLock 提供了更多的功能,如可中断的锁请求、超时锁请求、非阻塞地尝试获取锁、以及实现公平锁机制。

🦆
什么是 volatile 关键字?什么时候使用 volatile?

volatile 是 Java 中的一个关键字,表示一个变量可以被多个线程访问,并且其值的改变会立即被其他线程感知。volatile 保证了变量的可见性,但不保证操作的原子性。volatile 适用于某些轻量级的同步场景,如标志变量、状态指示器等。