1. wait notify notifyAll
wait notify notifyAll 调用必须是获取锁对象的时候调用才有效果,否则会抛出异常,需要配置synchronized一起使用;
- wait: 释放线程锁,并使当前线程进入休眠状态;
- notify: 唤醒一个wait状态的线程,进去争抢锁资源的队列;
- notifyAll: 唤醒所有争抢当前锁的线程,并且这个线程处于wait状态;
2. 实现逻辑
- 首先有一个队列;
- 生产者生产到队列上限以后停止生产,唤醒消费者进行消费,自身进入休眠状态;
- 消费者开始消费队列,直到队列消费完,然后唤醒生产者进行生产,自身进入休眠状态;
3. 代码
package com.cans.product;
import java.util.LinkedList;
/**
* 商品库
*
* @author shenc
* @date 2023-01-21 17:23
**/
public class GoodsStack {
/**
* 队列最大值
*/
private static final int COUNT = 5;
private static volatile Boolean isStop = false;
private static final LinkedList<String> products = new LinkedList<>();
public static void main(String[] args) {
Thread makeThread = new Thread(new ProductMake());
Thread consumerThread = new Thread(new ProductConsumer());
makeThread.start();
consumerThread.start();
}
/**
* 生产者
*/
public static class ProductMake implements Runnable {
@Override
public void run() {
int i = 0;
// 生产总数
int count = 20;
while (i < count) {
synchronized (products) {
while (products.size() >= COUNT) {
products.notifyAll();
try {
products.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String goods = "P:" + ++i;
products.add(goods);
if(i == count){
products.notifyAll();
}
System.out.println(Thread.currentThread().getName() + "生产商品:" + goods);
}
}
isStop = true;
}
}
public static class ProductConsumer implements Runnable {
@Override
public void run() {
synchronized (products) {
while (true) {
while (products.isEmpty()){
if(Boolean.TRUE.equals(isStop)){
return;
}
products.notifyAll();
try {
products.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String goods = products.removeFirst();
System.out.println(Thread.currentThread().getName() + "消费商品:" + goods);
}
}
}
}
}
运行结果:
Thread-0生产商品:P:1
Thread-0生产商品:P:2
Thread-0生产商品:P:3
Thread-0生产商品:P:4
Thread-0生产商品:P:5
Thread-1消费商品:P:1
Thread-1消费商品:P:2
Thread-1消费商品:P:3
Thread-1消费商品:P:4
Thread-1消费商品:P:5
Thread-0生产商品:P:6
Thread-0生产商品:P:7
Thread-0生产商品:P:8
Thread-0生产商品:P:9
Thread-0生产商品:P:10
Thread-1消费商品:P:6
Thread-1消费商品:P:7
Thread-1消费商品:P:8
Thread-1消费商品:P:9
Thread-1消费商品:P:10
Thread-0生产商品:P:11
Thread-0生产商品:P:12
Thread-0生产商品:P:13
Thread-0生产商品:P:14
Thread-0生产商品:P:15
Thread-1消费商品:P:11
Thread-1消费商品:P:12
Thread-1消费商品:P:13
Thread-1消费商品:P:14
Thread-1消费商品:P:15
Thread-0生产商品:P:16
Thread-0生产商品:P:17
Thread-0生产商品:P:18
Thread-0生产商品:P:19
Thread-0生产商品:P:20
Thread-1消费商品:P:16
Thread-1消费商品:P:17
Thread-1消费商品:P:18
Thread-1消费商品:P:19
Thread-1消费商品:P:20
4. 总结
- 使用wait以后当前线程进入休眠状态并且会阻塞当前线程,但是不会消耗CPU资源,这样会提高CPU的利用率;