1. 阻塞队列
- ArrayBlockingQueue 数组阻塞队列:采用数组实现的有界阻塞队列,按照先进先出的原则,初始化时,需要指定容量的大小,一旦创建,容量就不能改变。采用可重入锁进行并发控制,添加和删除操作采用的是同一个锁。
- LinkedBlockingQueue 链表阻塞队列:采用单向链表实现的阻塞队列,可以无界也可以有界,按照先进先出的原则,默认容量为 Integer.MAX_VALUE。锁是分离的,添加和删除操作使用两个不同的锁,在高并发场景下,生产者和消费者可以并行的操作队列中的数据,所以提高了并发性能。
- PriorityBlockingQueue 优先级阻塞队列:支持优先级排序的阻塞队列。可以通过实现 compareTo 方法来指定元素比较规则,也可以使用 Comparator 比较器来指定比较规则。Comparable和Comparator的区别
- SynchronousQueue 同步队列:它是一种不保存元素的阻塞队列,通过新建一个线程来处理新任务。是一种轻量级的ArrayBlockingQueue,在只有一个生产者和一个消费者的场景下性能较好。
2. 实现生产者消费者模式
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueTest {
public static void main(String[] args) {
ArrayBlockingQueue<Integer> 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 (InterruptedException 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 (InterruptedException e) {
e.printStackTrace();
}
}
}