参考博客:
- java wait()方法用法详解:https://www.jianshu.com/p/def7f016dd5e
- 你真的懂wait、notify和notifyAll吗:https://www.jianshu.com/p/25e243850bd2?appinstall=0
- 诡异的java.lang.IllegalMonitorStateException:https://blog.csdn.net/historyasamirror/article/details/6709693
java.lang.Object类的方法:wait(), notify(), notifyAll()等方法介绍
- wait()的作用是让当前线程进入等待状态(等待阻塞),同时,wait()也会让当前线程释放它所持有的锁。“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒,线程状态从等待阻塞转为同步阻塞(等待池转为锁池)。
- wait(long timeout)作用是让当前线程进入等待状态(等待阻塞),同时,wait()也会让当前线程释放它所持有的锁。“直到其他线程调用此对象的 notify() 方法,notifyAll() 方法或者超过指定的时间,当前线程被唤醒,线程状态从等待阻塞转为同步阻塞(等待池转为锁池)。
- notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程,线程状态从等待阻塞转为同步阻塞(等待池转为锁池);notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。
- wait(), notify(), notifyAll(),调用的时候也必须先获取到锁,否则会抛出异常 IllegalMonitorStateException。
使用wait()和notify()实现生产消费模型,代码如下:
package com.ming.interview.multithread;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: ProduceConsume
* @Description: TODO(生产消费模型:使用wait()和notify()实现)
* @author root
* @date 2020年3月28日
*
*/
public class ProduceConsume {
private Buffer buffer = new Buffer();
/**
* @Title: produce
* @Description: TODO(生产)
* @param 参数
* @return void 返回类型
* @throws
*/
public void produce() {
synchronized (this) {
while(buffer.isFull()) {
try {
System.out.println(Thread.currentThread().toString() + " consume:库存饱和,生产等待");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffer.add();
this.notifyAll();
}
}
public void consume() {
synchronized (this) {
while(buffer.isEmpty()) {
try {
System.out.println(Thread.currentThread().toString() + " consume:库存不足,消费等待");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffer.remove();
this.notifyAll();
}
}
/**
* @ClassName: Buffer
* @Description: TODO(缓冲区)
* @author root
* @date 2020年3月28日
*/
private class Buffer {
private static final int MAX_CAPACITY = 1; //缓冲集合最大容量
private List<Object> innerList = new ArrayList<Object>(MAX_CAPACITY); //缓冲集合
void add() {
if (isFull()) {
throw new IndexOutOfBoundsException();
} else {
innerList.add(new Object());
}
System.out.println(Thread.currentThread().toString() + " add");
}
void remove() {
if (isEmpty()) {
throw new IndexOutOfBoundsException();
} else {
innerList.remove(MAX_CAPACITY - 1);
}
System.out.println(Thread.currentThread().toString() + " remove");
}
boolean isEmpty() {
return innerList.isEmpty();
}
boolean isFull() {
return innerList.size() == MAX_CAPACITY;
}
}
public static void main(String[] args) {
//生产消费对象
ProduceConsume productConsume = new ProduceConsume();
//生产线程
Runnable produceRunnable = new Runnable() {
private int count = 10;
@Override
public void run() {
while(count-- > 0) {
productConsume.produce();
}
}
};
//消费线程
Runnable consumeRunnable = new Runnable() {
private int count = 10;
@Override
public void run() {
while(count-- > 0) {
productConsume.consume();
}
}
};
//消费线程
for (int i = 0; i < 2; i++) {
new Thread(consumeRunnable).start();
}
//生产线程
for (int i = 0; i < 2; i++) {
new Thread(produceRunnable).start();
}
}
}