阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
下面模拟一种场景,其两个线程,一个放内容到队列中,一个取线程,代码如下:
public class BlockingQueueTest {
public static void main(String[] args) {
BlockingQueue<String> bq = new ArrayBlockingQueue<String>(10);
new Thread(new Runnable() {
@Override
public void run() {
try {
int i = 0;
while(true) {
i++;
System.out.println("放入:"+i);
bq.put(i+""+new Date());
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true) {
String i =bq.take();
System.out.println("取出:"+i);
Thread.sleep(2000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
从上面的代码可以推测,第一个线程是一秒钟放一次,第二个线程是两秒钟取一次,阻塞队列的长度为10,那么可以推测,一开始是每放入两次取一次,那么在放入20次后阻塞队列才会放慢,此刻开始才是放入和取出循环操作,运行结果如下。
放入:1
取出:1Mon May 10 21:27:08 CST 2021
放入:2
放入:3
取出:2Mon May 10 21:27:09 CST 2021
放入:4
放入:5
取出:3Mon May 10 21:27:10 CST 2021
放入:6
放入:7
取出:4Mon May 10 21:27:11 CST 2021
放入:8
取出:5Mon May 10 21:27:13 CST 2021
放入:9
放入:10
取出:6Mon May 10 21:27:14 CST 2021
放入:11
放入:12
取出:7Mon May 10 21:27:15 CST 2021
放入:13
放入:14
取出:8Mon May 10 21:27:16 CST 2021
放入:15
放入:16
取出:9Mon May 10 21:27:17 CST 2021
放入:17
放入:18
取出:10Mon May 10 21:27:18 CST 2021
放入:19
放入:20
取出:11Mon May 10 21:27:19 CST 2021
放入:21
放入:22
取出:12Mon May 10 21:27:20 CST 2021
放入:23
取出:13Mon May 10 21:27:21 CST 2021
放入:24
取出:14Mon May 10 21:27:22 CST 2021
放入:25
取出:15Mon May 10 21:27:23 CST 2021
放入:26
取出:16Mon May 10 21:27:24 CST 2021
放入:27
取出:17Mon May 10 21:27:25 CST 2021
放入:28
取出:18Mon May 10 21:27:26 CST 2021
放入:29
取出:19Mon May 10 21:27:27 CST 2021
放入:30
这里有一篇文章写的很详细:https://www.cnblogs.com/bjxq-cs88/p/9759571.html