一、wait和notify简单介绍
在使用wait和notify这两个Object类的方法的时候,要确保拥有对象的控制权,否则回报java.lang.IllegalMonitorStateException 这样的错误,那么可以通过使用加锁的机制来保证,如使用synchronized关键字实现的实例方法或者代码块。wait是释放对象的控制权,notify可以唤醒一个等待获取对象控制权的线程。
二、实现生产者消费者
生产者向库存生产产品,消费者从库存消费产品,当库存满的时候生产者停止生产,等待消费者消费,当库存没有产品的时候,消费者等待生产者生产。下面的实例涉及到库存Stock类, 生产者Producer类, 消费者Consumer类。
库存类代码:
public class Stock {
private LinkedListlist =new LinkedList<>();
public void produce()throws InterruptedException {
synchronized(list){
if (list.size() >=100) {
list.wait();
}
list.add(1);
System.out.println("生产者生产了一个 剩余:" +list.size());
list.notify();
}
}
public void consume()throws InterruptedException {
synchronized(list){
if (list.size() <=0){
list.wait();
}
list.remove();
System.out.println("消费者消费了一个 剩余:" +list.size());
list.notify();
}
}
}
在库存类中如果不用list, 而是用一个Integer类型的size,当生产者生产size增加,消费者消费size减小会报错,因为当size增加后,消费者获取的对象控制权已不是原来的那个。
生产者类代码:
public class Producerextends Thread
{
private Stockstock;
public Producer() {
}
public Producer(Stock stock) {
this.stock = stock;
}
@Override
public void run() {
while(true){
try {
stock.produce();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者类代码:
public class Consumerextends Thread {
private Stockstock;
public Consumer(){
}
public Consumer(Stock stock){
this.stock = stock;
}
@Override
public void run() {
while(true){
try {
stock.consume();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
再写一个main函数:
public class MainClass {
public static void main(String[] args){
Stock stock =new Stock();
Producer producer =new Producer(stock);
Consumerconsumer=new Consumer(stock);
producer.start();
consumer.start();
}
}
网友评论