java面试题-notify()和notifyAll()有什么区别?
在Java多线程编程中,notify()
和 notifyAll()
是两个重要的方法,用于线程间的通信。这两个方法都与对象的锁池和等待池有关,但在使用时需要注意它们之间的区别。本教程将详细讨论notify()
和 notifyAll()
的概念、区别,并提供相应的代码示例,帮助初学者更好地理解这两个方法的使用。
1. 等待池和锁池的概念
在深入讨论 notify()
和 notifyAll()
之前,我们需要理解两个重要的概念:
等待池: 当一个线程调用某个对象的
wait()
方法时,该线程会释放该对象的锁并进入等待池。等待池中的线程不会去竞争对象的锁。锁池: 只有获得了对象的锁,线程才能执行对象的
synchronized
代码。对象的锁每次只能被一个线程获取,其他线程只能在锁池中等待。
2. notify() 和 notifyAll() 的区别
2.1 notify()
notify()
方法用于随机唤醒对象的等待池中的一个线程,使其进入锁池。
2.2 notifyAll()
notifyAll()
方法用于唤醒对象的等待池中的所有线程,使它们都进入锁池。
3. 示例代码演示
public class TestNotifyNotifyAll {
private static Object obj = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println("t1 开始执行");
synchronized (obj) {
try {
System.out.println("t1 开始等待");
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("t1 结束执行");
});
Thread t2 = new Thread(() -> {
System.out.println("t2 开始执行");
synchronized (obj) {
try {
System.out.println("t2 开始等待");
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("t2 结束执行");
});
t1.start();
t2.start();
// 启动 t3 线程,调用 notify() 方法
Thread t3 = new Thread(() -> {
synchronized (obj) {
System.out.println("随机唤醒其他线程");
obj.notify();
}
});
t3.start();
// 启动 t4 线程,调用 notifyAll() 方法
Thread t4 = new Thread(() -> {
synchronized (obj) {
System.out.println("唤醒其他所有线程");
obj.notifyAll();
}
});
t4.start();
}
}
4. 代码解释
t1
和t2
线程分别调用obj.wait()
进入等待池,等待被唤醒。t3
线程调用obj.notify()
随机唤醒t1
或t2
中的一个线程。t4
线程调用obj.notifyAll()
唤醒所有等待池中的线程。
5. 执行结果
执行以上代码,将得到如下输出:
t1 开始执行
t1 开始等待
t2 开始执行
t2 开始等待
随机唤醒其他线程
唤醒其他所有线程
t2 结束执行
t1 结束执行
6. 总结
通过本教程,我们深入理解了 notify()
和 notifyAll()
方法在Java中的用法和区别。了解这两个方法对于更好地处理多线程编程中的线程通信至关重要,确保在适当的时候唤醒等待池中的线程。
正文到此结束
- 本文标签: Java 面试题
- 本文链接: https://www.jietongc.com/article/86
- 版权声明: 本文由大熊科技原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权