面试题答案
一键面试-
自定义比较器(Comparator): 首先,定义
Task
类,包含任务的紧急程度等属性。然后,实现Comparator
接口来定义优先级比较规则。class Task implements Runnable { private int priority; private String taskName; public Task(int priority, String taskName) { this.priority = priority; this.taskName = taskName; } public int getPriority() { return priority; } @Override public void run() { System.out.println("Running task: " + taskName + " with priority: " + priority); } } class TaskComparator implements Comparator<Task> { @Override public int compare(Task t1, Task t2) { // 假设数字越小优先级越高 return Integer.compare(t1.getPriority(), t2.getPriority()); } }
-
PriorityBlockingQueue在多线程环境下的线程安全和优先级顺序:
- 线程安全:
PriorityBlockingQueue
本身是线程安全的,它通过内部使用ReentrantLock
来保证多线程环境下的安全访问。在添加元素(offer
、put
等方法)和取出元素(poll
、take
等方法)时,会获取锁,从而防止多个线程同时修改队列,保证线程安全。 - 优先级顺序:
PriorityBlockingQueue
内部使用堆数据结构来维护元素的顺序。当添加元素时,会根据自定义的Comparator
将元素插入到合适的位置以维持堆的性质(小顶堆,即根节点是最小元素)。当取出元素时,总是取出堆顶元素,也就是优先级最高的元素。
- 线程安全:
-
代码示例验证:
import java.util.concurrent.PriorityBlockingQueue; public class PriorityQueueExample { public static void main(String[] args) { PriorityBlockingQueue<Task> taskQueue = new PriorityBlockingQueue<>(10, new TaskComparator()); // 创建并添加任务 taskQueue.add(new Task(3, "Task C")); taskQueue.add(new Task(1, "Task A")); taskQueue.add(new Task(2, "Task B")); // 启动线程处理任务 Thread worker1 = new Thread(() -> { while (true) { try { Task task = taskQueue.take(); task.run(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); worker1.start(); try { // 主线程等待一段时间 Thread.sleep(2000); worker1.interrupt(); worker1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }
在上述代码中,TaskComparator
定义了任务的优先级比较规则,PriorityBlockingQueue
根据此规则维护任务的优先级顺序。在多线程环境下,PriorityBlockingQueue
的线程安全机制保证了多个线程对队列操作的正确性。运行PriorityQueueExample
的main
方法,会按照任务的优先级顺序依次执行任务。