redis有一个数据类型叫list(列表),它的每个子元素都是 string 类型的双向链表。我们可以通过 push、pop 操作从链表的头部或者尾部添加删除元素。这使得 list 既可以用作栈,也可以用作队列。假如,我们有一个队列系统,把一个个任务放到队列中,另一个进程就把队列中的任务取出来执行。放到队列我们使用lpush,也就是往双向链表的尾部填充一个元素(生产者)。另一个进程使用rpop往头部取出元素来执行(消费者)。
但这么做有个问题,即需要不停的调用rpop方法查看List中是否有待处理消息。每调用一次都会发起一次连接,这会造成不必要的浪费。如果使用Thread.sleep()方法让消费者线程隔一段时间再消费,会产生两个问题,一个是如果生产者速度大于消费者消费速度,消息队列长度会一直增大,时间久了会占用大量内存空间;还有一个是如果睡眠时间过长的话不能处理一些时效性的消息,睡眠时间过短的话也会在连接上造成比较大的开销。
所以可以使用brpop指令,这个指令只有在有元素时才返回,没有则会阻塞直到超时返回null。