Я попытаюсь объяснить эту проблему с помощью полнофункционального кода. Но прежде чем углубляться в код, я хотел бы объяснить, что такое PriorityBlockingQueue
PriorityBlockingQueue : PriorityBlockingQueue является реализацией BlockingQueue. Он принимает задачи вместе с их приоритетом и передает задачу с наивысшим приоритетом для выполнения в первую очередь. Если какие-либо две задачи имеют одинаковый приоритет, нам нужно предоставить некоторую настраиваемую логику, чтобы решить, какая задача идет первой.
Теперь давайте сразу перейдем к коду.
Класс драйвера : Этот класс создает исполнителя, который принимает задачи, а затем отправляет их на выполнение. Здесь мы создаем две задачи: одну с низким приоритетом, а другую с высоким приоритетом. Здесь мы говорим исполнителю запустить MAX из 1 потоков и использовать PriorityBlockingQueue.
public static void main(String[] args) {
/*
Minimum number of threads that must be running : 0
Maximium number of threads that can be created : 1
If a thread is idle, then the minimum time to keep it alive : 1000
Which queue to use : PriorityBlockingQueue
*/
PriorityBlockingQueue queue = new PriorityBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(0,1,
1000, TimeUnit.MILLISECONDS,queue);
MyTask task = new MyTask(Priority.LOW,"Low");
executor.execute(new MyFutureTask(task));
task = new MyTask(Priority.HIGH,"High");
executor.execute(new MyFutureTask(task));
}
MyTask class : MyTask реализует Runnable и принимает приоритет в качестве аргумента в конструкторе. Когда эта задача выполняется, она печатает сообщение, а затем переводит поток в спящий режим на 1 секунду.
public class MyTask implements Runnable {
public int getPriority() {
return priority.getValue();
}
private Priority priority;
public String getName() {
return name;
}
private String name;
public MyTask(Priority priority,String name){
this.priority = priority;
this.name = name;
}
@Override
public void run() {
System.out.println("The following Runnable is getting executed "+getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MyFutureTask class : Поскольку мы используем PriorityBlocingQueue для хранения наших задач, наши задачи должны быть заключены в FutureTask, а наша реализация FutureTask должна реализовывать Comparable интерфейс. Интерфейс Comparable сравнивает приоритет двух разных задач и отправляет задачу с наивысшим приоритетом на выполнение.
public class MyFutureTask extends FutureTask<MyFutureTask>
implements Comparable<MyFutureTask> {
private MyTask task = null;
public MyFutureTask(MyTask task){
super(task,null);
this.task = task;
}
@Override
public int compareTo(MyFutureTask another) {
return task.getPriority() - another.task.getPriority();
}
}
Класс приоритета : Самоочевидный класс приоритета.
public enum Priority {
HIGHEST(0),
HIGH(1),
MEDIUM(2),
LOW(3),
LOWEST(4);
int value;
Priority(int val) {
this.value = val;
}
public int getValue(){
return value;
}
}
Теперь, когда мы запустим этот пример, мы получим следующий вывод
The following Runnable is getting executed High
The following Runnable is getting executed Low
Несмотря на то, что мы сначала отправили приоритет LOW, но позже задачу HIGH priority, но поскольку мы используем PriorityBlockingQueue, сначала будет выполняться задача с более высоким приоритетом.