synchronized wait notify
时间: 2023-04-13 13:01:01 浏览: 135
synchronized、wait和notify都是Java中用于实现线程同步的关键字和方法。
synchronized用于实现线程的互斥访问,即同一时刻只能有一个线程访问被synchronized修饰的代码块或方法。
wait和notify则是用于线程之间的通信。wait方法会使当前线程进入等待状态,直到其他线程调用notify方法来唤醒它。notify方法则是用于唤醒一个正在等待的线程。
在使用wait和notify时,必须先获取对象的锁,即在synchronized代码块或方法中使用。否则会抛出IllegalMonitorStateException异常。
相关问题
wait notify
Java多线程中的wait和notify是线程间通信的两个重要方法。
wait方法是使当前线程进入等待状态,直到其他线程调用notify方法唤醒它。wait方法必须在synchronized块中调用,否则会抛出IllegalMonitorStateException异常。
notify方法是唤醒一个正在等待的线程,使其从wait方法中返回。notify方法也必须在synchronized块中调用。
wait和notify方法的使用可以实现线程间的协作,例如生产者-消费者模型中,生产者线程生产数据后调用notify方法唤醒消费者线程,消费者线程消费数据后调用notify方法唤醒生产者线程。
synchronized notify
### Java 多线程中 `synchronized` 和 `notify` 的使用方法及差异
#### 使用场景与基本概念
`synchronized` 关键字用于控制多个线程对共享资源的访问。它确保同一时刻只有一个线程可以执行被此关键字修饰的方法或代码块,从而实现同步机制[^1]。
```java
public synchronized void method() {
// 同步方法体
}
```
对于静态方法,则是对整个类加锁;而对于实例方法则是对该对象加锁。此外还可以通过显式的同步代码块来指定要锁定的对象:
```java
synchronized (object) {
// 需要同步保护的关键区域
}
```
而 `notify()` 是 Object 类的一个本地方法,作用是在当前线程持有某个对象监视器的情况下调用该方法会随机唤醒在此对象上等待的一个单个线程(如果存在)。需要注意的是,在调用了 `notify()` 或者 `notifyAll()` 方法之后并不会立即释放锁,而是等到当前线程退出临界区才会真正释放锁并允许其他被唤醒的线程继续运行[^2]。
#### 实际应用案例分析
考虑一个简单的生产者消费者模型例子,其中涉及到了栈操作——入栈 (`push`) 和出栈 (`pop`) 。为了防止并发情况下数据竞争问题的发生,这里采用了 `synchronized` 来保证每次只有一条路径能够修改列表状态,并且利用了 `wait()` 和 `notify()` 进行条件变量通知以协调不同角色之间的协作关系[^4]。
```java
public class MyStack {
private List<String> list = Collections.synchronizedList(new ArrayList<>());
public synchronized void push(String value) {
list.add(value);
notify();
}
public synchronized String pop() throws InterruptedException {
while (list.isEmpty()) {
wait(); // 当队列为空时阻塞当前线程直到有新元素加入
}
return list.remove(list.size() - 1);
}
}
```
在这个例子中,每当向栈内添加新的字符串时都会触发一次 `notify()` 调用,这可能会激活正在等待从栈顶取值的那个消费方线程。同样地,当尝试移除最后一个项目之前发现容器已经清空,则应使自己进入挂起态直至收到相应信号为止。
#### 主要区别总结
- **功能定位**:`synchronized` 提供了一种简单有效的互斥手段用来保障特定区域内不会发生竞态条件;相反,`notify()/notifyAll()` 则是用来处理基于事件驱动的通知逻辑,即告知处于等待池里的某一线程现在有机会重新获取CPU时间片去完成其未竟之事。
- **适用范围**:前者适用于任何需要独占式访问某些敏感部位的情形之下;后者则更多见于那些涉及到多任务间通信调度的应用场合之中[^3]。
阅读全文