一、Object类的等待和唤醒方法
wait()和notify()方法并不是线程对象的方法,是Java中任何一个Java对象都有的方法,wait()和notify()方法都是建立在synchronized线程同步的基础之上。
- void wait():导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法
- void notify(): 唤醒正在等待对象监视器的单个线程
- void notifyAll(): 唤醒正在等待对象监视器的所有线程
在知道wait()和notifyAll(),再结合synchronized线程同步,就可以组合一个等待唤醒机制。当资源没有的时候,执行wait(),使线程等待中,这是去产生资源,等有了资源,在执行notifyAll()唤醒所有等待的线程,程序继续执行。
// 使用while(true)循环不断的对程序进行询问
// synchronized线程同步,是资源同步
// 这里可以有甲乙两方来调用wait()和notifyAll()来进行线程等待和线程唤醒
// 通过相互切换来达到目的,逻辑写在中间
二、阻塞队列基本使用
阻塞队列的概念
阻塞队列提供了可阻塞的put和take方法,当队列为空时,消费者使用take方法从队列中获取数据就会被阻塞,直到队列有数据可用;当队列是满的,生产者使用put方法向队列里添加数据就会被阻塞,直到队列中数据被消费有空闲位置可用。
方法
- ArrayBlockingQueue:基于数组实现的有界阻塞队列。
- LinkedBlockingQueue:基于链表实现的有界阻塞队列,最大为int的最大值。
- put(anObject): 将参数放入队列,如果放不进去会阻塞
- take(): 取出第一个数据,取不到会阻塞
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
// 创建阻塞队列的对象,容量为 2
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(2);
// 存储元素
arrayBlockingQueue.put("存储第1个数据");
arrayBlockingQueue.put("存储第2个数据");
// 取元素
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take());
System.out.println("程序结束了");
}
}
这里显示程序执行完了
假如我们在多取一次
// 取元素
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take());
这里就显示了,程序在阻塞
三、总结
相对与使用wait()和notifyAll()组成的等待唤醒机制,阻塞队列感觉相对更加方便,处理也方便,把更多的关注点放在业务处理上。