java多线程的wait(), notify(), notifyAll()的用法

参考博客:

  1. java wait()方法用法详解:https://www.jianshu.com/p/def7f016dd5e
  2. 你真的懂wait、notify和notifyAll吗:https://www.jianshu.com/p/25e243850bd2?appinstall=0
  3. 诡异的java.lang.IllegalMonitorStateException:https://blog.csdn.net/historyasamirror/article/details/6709693

java.lang.Object类的方法:wait(), notify(), notifyAll()等方法介绍

  1. wait()的作用是让当前线程进入等待状态(等待阻塞),同时,wait()也会让当前线程释放它所持有的锁。“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒,线程状态从等待阻塞转为同步阻塞(等待池转为锁池)。
  2. wait(long timeout)作用是让当前线程进入等待状态(等待阻塞),同时,wait()也会让当前线程释放它所持有的锁。“直到其他线程调用此对象的 notify() 方法,notifyAll() 方法或者超过指定的时间,当前线程被唤醒,线程状态从等待阻塞转为同步阻塞(等待池转为锁池)。
  3. notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程,线程状态从等待阻塞转为同步阻塞(等待池转为锁池);notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。
  4. 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();
		}
	}
}

发布了110 篇原创文章 · 获赞 57 · 访问量 40万+

猜你喜欢

转载自blog.csdn.net/menghuanzhiming/article/details/105157534