阻塞队列
例如有三个人包饺子,A负责擀面皮,B和C负责包,A的工作是直接受到B和C影响到,如果B或者C其中一个出现了问题,A擀出来的面皮就会堆积,B或者C包的速度就会下降,这种问题就叫做耦合
通俗来讲就是让A的工作降低对B和C的依赖,A擀好的面皮放在一个盘子里,B和C根据自己的速度包饺子,盘子满了A就休息,盘子快没有了A就要加快速度擀面皮,而这个盘子就是所说的阻塞队列
针对一个已经满了的队列进行入队列,此时入队列操作就会阻塞,一直阻塞到队列不满之后
针对一个已经空了的队列进行出队列,此时出队列操作就会阻塞,一直阻塞到队列不空之后
阻塞队列的特点
1.让我们的代码解耦合
2.削峰填谷(就是让摆脱依赖性)
自主实现一个阻塞队列
阻塞队列相当于是一个环形链表,需要的基本变量就需要一个数组,队首head来判断队列是否为空,队尾来tail判断队列是否满了,size来记录数组内的元素,构造方法来初始化数组

先写一个普通的入队列,先检查队列是否满了满的就返回不做任何操作,数组未满就可以往里添加元素,将元素添加到队尾的位置,更新队尾的位置,当队尾的值已经超过了数组的长度,就说明队列已经满了,让队尾直接指向0,这个队列就不能在添加元素,实现循环队列的效果,更新数组元素的个数

出队列,首先先判断队列是否为空,为空则返回null,不做任何操作,定义一个elem变量使其为null,从队首开始取元素,取出元素的位置就置为null,更新队首的位置,如果head超过了数组的长度,就将其置为0,更新数组内的元素个数

普通队列完成后,就可以进行阻塞,进行阻塞前还需要考虑线程是否是安全的,由于队列的读写操作涉及到多线程的并发访问,最简单的办法就是加锁来同步共享资源的访问,这就要考虑到加锁的位置了
随便创建一个对象来给后续的锁,如果把锁加在了后面写的操作就会导致线程会多加一次,因为cpu的调度时随机的,调度时可能会失去一次判断,从而导致size进行了多加

所以锁要把线程的读和写的操作捆绑到一起,这样就不会让size进行多加的情况

最后就进行阻塞,阻塞可以使用wait,刚好wait的使用方法是需要写在锁里面,队列满/空了需要取出一个元素才能往里面放/取,take里面的nofity去唤醒put里的wait


如果使用if来判断队列是否为空/满,可能会导致虚假唤醒,因为if语句只会检查一次条件,第一次条件比满足,线程进入等待,当线程被唤醒时,就不会进行条件判断,从而执行后续的代码,这就导致了条件不满足从而继续执行的错误,所以要把if改写成while进行多次检查,避免线程出错

最后在编写两个线程,一个叫生产者,一个是消费者,当我们在生产者加上个时间限制,就会生产一个元素消费一个元素
而在消费者处添加一个时间限制就会变成先成产满,然后消费一个在生产一个




浙公网安备 33010602011771号