问答平台(5),阻塞队列

阻塞队列

阻塞队列-图示

1
2
3
4
5
6
不使用阻塞队列:
- 如果生产者生产速度快、消费者消费速度慢的话,很快就会达到性能瓶颈。如:线程2没处理完数据,线程1依旧在不停的生产数据、没有被阻塞,则会占用CPU资源。
- 如果消费者消费速度快、生产者生产速度慢的话,占用系统CPU资源。
使用阻塞队列:
- 队列满,生产者线程被阻塞,不占用系统资源。
- 队列空相反。

BlockingQueue

1
2
- 解决线程通信的一个接口。在生产者、消费者之间起到缓冲作用,避免浪费CPU资源。
- 阻塞方法:put、take。

生产者/消费者模式

1
2
- 生产者:产生数据的线程。
- 消费者:使用数据的线程。

实现类

1
2
3
- ArrayBlockingQueue
- LinkedBlockingQueue
- PriorityBlockingQueue、SynchronousQueue、DelayQueue 等。

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// BlockingQueueTests.java
public class BlockingQueueTests {

public static void main(String[] args) {
// ArrayBlockingQueue
BlockingQueue queue = new ArrayBlockingQueue(10);
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}

class Producer implements Runnable {

private BlockingQueue<Integer> queue;

public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}

@Override
public void run() {
try {
for (int i = 0; i < 100; i++) {
Thread.sleep(20);
queue.put(i);
System.out.println(Thread.currentThread().getName() + "生产:" + queue.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

class Consumer implements Runnable {

private BlockingQueue<Integer> queue;

public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}

@Override
public void run() {
try {
while (true) {
Thread.sleep(new Random().nextInt(1000));
queue.take();
System.out.println(Thread.currentThread().getName() + "消费:" + queue.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

问答平台(5),阻塞队列
https://lcf163.github.io/2020/05/30/问答平台(5),阻塞队列/
作者
乘风的小站
发布于
2020年5月30日
许可协议