队列:FIFO先进先出
ArrayBlockingQueue
阻塞式顺序表 - 基于数组来实现,在使用的时候也需要指定容量,而且容量指定好之后不可改变。
- put方法是一个阻塞方法,如果添加元素时,容量已经满了,此时线程被阻塞,直到有元素被取出,才可以添加进去
- offer方法,如果添加元素时,容量已经满了,此时线程会返回一个false,当线程没有满的,返回true
- add方法,如果添加元素时,容量已经满了,此时线程会报出IllegalStateException异常
LinkedBlockingQueue
阻塞式链表 - 基于节点来进行说数据的存储。在使用的时候可以指定容量也可以不指定。如果指定了容量,则容量不可变。如果不指定容量,则默认容量为Integer.MAX_VALUE,所以一般认为这种、情况下,队列是没有界限的。
插入方法:
- add(E e) : 添加成功返回true,失败抛IllegalStateException异常
- offer(E e) : 成功返回 true,如果此队列已满,则返回 false。
- put(E e) :将元素插入此队列的尾部,如果该队列已满,则一直阻塞
删除方法:
- remove(Object o) :移除指定元素,成功返回true,失败返回false
- poll() : 获取并移除此队列的头元素,若队列为空,则返回 null
- take():获取并移除此队列头元素,若没有元素则一直阻塞。
检查方法
- element() :获取但不移除此队列的头元素,没有元素则抛异常
- peek() :获取但不移除此队列的头;若队列为空,则返回 null。
注意
- ArrayBlockingQueue使用的是读写同锁,LinkedBlockingQueue使用的是读写两套锁
- 也就是ArrayBlockingQueue不可以读和写同时操作,而LinkedBlockingQueue可以读和写同时操作
- 因为ArrayBlockingQueue的计数器使用的是int,而LinkedBlockingQueue使用的原子性int所以,同时ArrayBlockingQueue使用的一套锁(读写同锁),而LinkedBlockingQueue使用的是两套锁(读写分别使用相应的锁)
PriorityBlockingQueue - 优先级阻塞式队列 - 这个队列会对放入的元素进行自然排序,也就意味着队列中的元素对应的类要实现Comparable。但是在迭代的时候不保证排序。
- 不支持传入null值
- 传入的对象必须实现Comparable接口
- add方法添加元素到队列中,成功返回true,否则返回false
- offer方法添加元素到队列中,成功返回true,否则返回false,元素不能为空,否则抛出空指针异常
- put方法添加元素到队列中,如果队列中没有多余的空间,该方法会一直阻塞,直到队列中有多余的空间
- take方法从队列中获取值,如果队列没有值,线程会一直被堵塞,直到队列中有值,并且该方法取的值。
- poll方法从队列中获取值,如果队列有值,返回值,没有值返回null
SynchronousQueue - 同步队列 - 容量默认为1,而且只能为1。