多线程-Object类的等待和唤醒方法与阻塞队列

159 阅读2分钟

一、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("程序结束了");
    }

}

image.png 这里显示程序执行完了

假如我们在多取一次

// 取元素
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take());
System.out.println(arrayBlockingQueue.take());

这里就显示了,程序在阻塞 image.png

三、总结

相对与使用wait()和notifyAll()组成的等待唤醒机制,阻塞队列感觉相对更加方便,处理也方便,把更多的关注点放在业务处理上。