成都网站建设技术,安徽平台网站建设设计,综合类门户网站有哪些,wordpress精美主题一、什么是堵塞队列 堵塞队列#xff08;Blocking Queue#xff09;是一种特殊类型的队列#xff0c;它具有一些特定的行为和限制。在堵塞队列中#xff0c;当队列为空时#xff0c;尝试从队列中取出元素的操作将会被阻塞#xff0c;直到队列中有可用元素#xff1b;当…一、什么是堵塞队列 堵塞队列Blocking Queue是一种特殊类型的队列它具有一些特定的行为和限制。在堵塞队列中当队列为空时尝试从队列中取出元素的操作将会被阻塞直到队列中有可用元素当队列已满时尝试向队列中添加元素的操作也会被阻塞直到队列有空闲位置。 堵塞队列常用于多线程编程场景中用于实现线程间的安全通信和协调。它提供了一种简单而有效的方式来实现线程的等待和唤醒机制使得线程能够在合适的时机进行阻塞或继续执行。 常见的堵塞队列实现包括 ArrayBlockingQueue基于数组的有界堵塞队列。LinkedBlockingQueue基于链表的可选有界默认无界堵塞队列。PriorityBlockingQueue支持优先级排序的堵塞队列。SynchronousQueue一个不存储元素的特殊堵塞队列用于实现线程间的直接传输。 使用堵塞队列可以有效地解决线程间的同步和通信问题简化了多线程编程的复杂性。 阻塞队列的典型应用场景生产者消费者模型 生产者消费者模型是一种常见的多线程协调工作的模式生产者和消费者之间通过阻塞队列进行通讯生产者生产出数据不用等待消费者来处理而是会直接放入到阻塞队列中消费者也不找生产者索要数据而是直接从阻塞队列中取。 生产者消费者模型的作用
有利于代码“解耦合” 生产者不用关心消费者的存在消费者也不需关心生产者的存在通过阻塞队列可以降低二者的关联关系。 “削峰填谷” 阻塞队列相当于一个“缓冲区”平衡了生产者和消费者的处理能力。
二、 代码实例 public static void main(String[] args) {BlockingDequeInteger blockingDeque new LinkedBlockingDeque();Thread t1 new Thread(() - {while (true) {try {Integer take blockingDeque.take();System.out.println(消费 take);} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();Thread t2 new Thread(() - {int value 0;while (true) {try {System.out.println(生产 value);blockingDeque.put(value);value;Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t2.start();}
结果 三、模拟实现堵塞队列 注意 1.我们刚才实现的put和take方法的几乎每一行代码都涉及到读写操作所以在多线程环境下这种非原子操作一定是不安全的我们需要对这两个方法进行加锁并用volatile修饰相应的变量来保证线程安全 2.我们需要实现两个阻塞功能可以使用wait和notify来进行线程阻塞和唤醒线程的操作 3.wait方法是可以被其他方法比如interrupt方法提前唤醒的此时队列还是空或满的状态那么继续执行代码仍然会出错所以当线程被提前唤醒时我们需要再次判断队列是否为空或满的状态如果是则继续等待如果不是则执行后面的逻辑因此使用while循环判断就可以解决上述问题~ public class MyBlockingQueue {private int[] array new int[100];private volatile int head;//队首元素下标private volatile int tail;//队尾元素下标private volatile int size;//有效元素个数synchronized public void put(int elem) throws InterruptedException {//判断队列是否为满while (size array.length){this.wait();}//插入元素array[tail] elem;tail;//循环队列//队尾元素下标如果超出数组长度则从头开始存储if(tail array.length){tail 0;}size;this.notify();}synchronized public int take() throws InterruptedException {//判断队列是非为空while (size 0){this.wait();}//取出元素int value array[head];head;//队首元素下标如果超出数组长度则从头开始if(head array.length){head 0;}size--;this.notify();return value;}}