ArrayBlockingQueue 是一个用数组实现的有界阻塞队列,其内部按先进先出的原则对元素进行排序,其中put方法和take方法为添加和删除的阻塞方法。
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; public class ArrayBlockingQueueDemo { //消费者和生产者持有同一个ArrayBlockingQueue的对象。其实,使用普通的List阻塞判断有没有值,也可以实现 // ArrayBlockingQueue的功能。 private final static ArrayBlockingQueue<Apple> queue= new ArrayBlockingQueue<>(1); public static void main(String[] args){ new Thread(new Producer(queue)).start(); new Thread(new Consumer(queue)).start(); } } class Apple { public Apple(){ } } /** * 生产者线程 */ class Producer implements Runnable{ private final ArrayBlockingQueue<Apple> mAbq; Producer(ArrayBlockingQueue<Apple> arrayBlockingQueue){ this.mAbq = arrayBlockingQueue; } @Override public void run() { while (true) { Produce(); } } private void Produce(){ try { Apple apple = new Apple(); //将元素插入此队列的尾部,如果该队列已满,则一直阻塞 mAbq.put(apple); System.out.println("生产:"+apple); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 消费者线程 */ class Consumer implements Runnable{ private ArrayBlockingQueue<Apple> mAbq; Consumer(ArrayBlockingQueue<Apple> arrayBlockingQueue){ this.mAbq = arrayBlockingQueue; } @Override public void run() { while (true){ try { TimeUnit.MILLISECONDS.sleep(1000); comsume(); } catch (InterruptedException e) { e.printStackTrace(); } } } private void comsume() throws InterruptedException { //获取并移除此队列头元素,若没有元素则一直阻塞 Apple apple = mAbq.take(); System.out.println("消费Apple="+apple); } }
有点需要注意的是ArrayBlockingQueue内部的阻塞队列是通过重入锁ReenterLock和Condition条件队列实现的,所以ArrayBlockingQueue中的元素存在公平访问与非公平访问的区别,对于公平访问队列,被阻塞的线程可以按照阻塞的先后顺序访问队列,即先阻塞的线程先访问队列。而非公平队列,当队列可用时,阻塞的线程将进入争夺访问资源的竞争中,也就是说谁先抢到谁就执行,没有固定的先后顺序。创建公平与非公平阻塞队列代码如下:
//默认非公平阻塞队列 ArrayBlockingQueue queue = new ArrayBlockingQueue(2);
//公平阻塞队列 ArrayBlockingQueue queue1 = new ArrayBlockingQueue(2,true);
------------------
原文:https://blog.csdn.net/javazejian/article/details/77410889?utm_source=copy