BlockingQue-阻塞式队列
一、概述
采用先进先出(FIFO)的阻塞式队列,在使用的时候往往需要指定容量,容量指定后往往不可变,当队列为空的时候,试图获取元素的线程会被阻塞,队列满的时候,试图向其中放入元素时会被阻塞,队列往往适应于生产消费的模型,在BlockingQueue中,不允许元素为null。
常见的实现类
①ArrayBlockingQueue-阻塞式顺序队列
// 指定了数组的大小(容量)
ArrayBlockingQueue queue = new ArrayBlockingQueue<>(5);
// 添加元素
queue.add(“a”);
queue.add(“b”);
queue.add(“c”);
queue.add(“d”);
queue.add(“e”);
// 队列已满
// 抛出IllegalStateException
// queue.add(“b”);
// 返回false
// boolean b = queue.offer(“b”);
// System.out.println(b);
// 永久阻塞
// queue.put(“b”);
// 定时阻塞
boolean b = queue.offer(“b”, 5, TimeUnit.SECONDS);
System.out.println(b);
System.out.println(queue);
}
底层依靠数组实现存储,容量需要指定且不可变
②LinkedBlockingQueue-阻塞式链式队列
依靠节点实现,是一个单向链表,容量可以不指定,不指定默认为Integer_MAX_VALUE.
BlockingQueue queue = new LinkedBlockingQueue<>();
// 队列为空
// 抛出NoSuchElementException
// System.out.println(queue.remove());
// 返回null
// System.out.println(queue.poll());
// 永久阻塞
// System.out.println(queue.take());
// 定时阻塞
System.out.println(queue.poll(5, TimeUnit.SECONDS));
③PriorityBlockingQueue-具有优先级的阻塞式队列
容量可以不指定,不指定容量为11,且可以扩容,依靠数组进行存储数据,且在放入数据会进行排序,但必须实现Comparable,单独指定排序规则时,需要传入Comparator,迭代遍历不保证排序。
public static void main(String[] args) throws InterruptedException {
// PriorityBlockingQueue<String> queue = new PriorityBlockingQueue<>();// queue.put("Bob");// queue.put("Eden");// queue.put("Grace");// queue.put("Alex");// queue.put("Cathy");// queue.put("Frank");// queue.put("David");// PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>(5,// new Comparator<Student>() {// @Override// public int compare(Student o1, Student o2) {// return o1.getAge() - o2.getAge();// }// });// PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>(5, (s1, s2) -> s1.getAge() - s2.getAge());PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>(5, Comparator.comparingInt(Student::getAge));queue.put(new Student("张三丰", 38, 59));queue.put(new Student("刘德华", 40, 61));queue.put(new Student("君莫笑", 28, 70));queue.put(new Student("洋洋", 30, 80));queue.put(new Student("阿斯顿", 27, 71));// for (int i = 0; i < 5; i++) {// System.out.println(queue.take());// }for (Student s : queue) {System.out.println(s);}}
}
class Student implements Comparable {
private String name;
private int age;
private int score;public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;
}public String getName() {return name;
}public void setName(String name) {this.name = name;
}public int getAge() {return age;
}public void setAge(int age) {this.age = age;
}public int getScore() {return score;
}public void setScore(int score) {this.score = score;
}@Override
public String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';
}// 按照分数降序排序
// 指定比较规则
// 升序:this - o
// 降序:o - this
@Override
public int compareTo(Student o) {return o.getScore() - this.getScore();
}
}