多线程下的并发库接口BlockingQueue,线程是安全的,典型应用场景是生产者-消费者,有ArrayBlockingQueue , DelayQueue , LinkedBlockingDeque , LinkedBlockingQueue , LinkedTransferQueue , PriorityBlockingQueue , SynchronousQueue 的子类去实现。
ArrayBlockingQueue
底层使用对象数组存储需要保存的数据,可在构造方法中指定数组的长度,构造函数中申明锁Lock和多条件判断状态
notEmpty和notFull(lock.newCondition()),add(E e),put(E e),offer(E e)等在插入元素之前都会判断是否为空,为空则抛出空指针异常。
组成:对象数组、一个标识这个队列的队尾下标putIndex,一个队首元素的索引下标takeIndex,一个记录元素个数的变量count(实际元素的个数).
原理:插入元素时先判断队列是否满(count与数组长度比较),满则等待,不满则插入到putIndex所指的位置且putIndex++,count++.
取数据从takeIndex索引处取数据,取完将takeIndex所指元素置空,takeIndex++,count--,此过程都会判断是否是队尾,队尾则从0下标继续开始
代码如下:
public class ArrayBlockQueueDemo { public static void main(String[] args) { BlockingQueue queue = new ArrayBlockingQueue(100); for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(new Random().nextInt(1000) ); } catch (InterruptedException e) { e.printStackTrace(); } String data = String.valueOf(System.currentTimeMillis()); try { queue.put(data); System.out.println("放入数据:" + data); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } String data = null; try { data = (String)queue.take(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("取出数据:"+data); } } }).start(); } } }
两个生产者产生数据 两个消费者消费数据
后面分享并发库下的其他集合