[英]get a PriorityBlockingQueue to be in the right order in java
I have tried to make a custom ThreadPoolExecuter that holds a PriorityBlockingQueue as his queue.我试图制作一个自定义的 ThreadPoolExecuter,它将 PriorityBlockingQueue 作为他的队列。 I have tried to make the queue to make the PriorityBlockingQueue to order his tasks from the lower priorty to the higher priority and I couldnt do it.
我试图让队列使 PriorityBlockingQueue 将他的任务从低优先级排序到高优先级,但我做不到。 I will be happy to get some help.
我很乐意得到一些帮助。
customExecuter code:自定义执行器代码:
public class CustomExecutor extends ThreadPoolExecutor implements Comparator<Task> {
private int maxPriority = 0;
private boolean isShutdown = false;
public CustomExecutor() {
super(Runtime.getRuntime().availableProcessors() / 2,
Runtime.getRuntime().availableProcessors() -1
,300,TimeUnit.MILLISECONDS,new PriorityBlockingQueue<>());
}
private <T> Future<T> submitTask(Task task) {
if (task.getPriority().getPriorityValue()>maxPriority)
maxPriority=task.getPriority().getPriorityValue();
if (isShutdown) {
System.out.println("Thread pool has already been shut down. Cannot submit task");
return null;
}
return super.submit(task);
}
public <T> Future<T> submit(Callable<T> callable,TaskType priority) {
Task task=new Task(callable,priority);
return submitTask(task);
}
//OTHER is default because it has the lowest priority(highest number)
public <T> Future<T> submit(Callable<T> callable) {
Task task=new Task(callable,TaskType.OTHER);
return submitTask(task);
}
public int getCurrentMax() {
return maxPriority;
}
public void gracefullyTerminate() {
isShutdown = true;
super.shutdown();
}
@Override
public int compare(Task o1, Task o2) {
return Integer.compare(o2.getPriority().getPriorityValue(), o1.getPriority().getPriorityValue());
}
Task code:任务代码:
public class Task implements Callable {
private Callable callable;
private TaskType priority;
public<T> Task(Callable<T> callable, TaskType priority) {
this.callable = callable;
this.priority = priority;
}
public TaskType getPriority() {
return priority;
}
public static <T> Task createTask(Callable<T> task, TaskType priority)
{
Task newTask=new Task(task,priority);
return newTask;
}
@Override
public Object call() throws Exception {
return callable.call();
}
enum for TaskType for the priority part:优先级部分的 TaskType 枚举:
public enum TaskType {
COMPUTATIONAL(1){
@Override
public String toString(){return "Computational Task";}
},
IO(2){
@Override
public String toString(){return "IO-Bound Task";}
},
OTHER(3){
@Override
public String toString(){return "Unknown Task";}
};
private int typePriority;
private TaskType(int priority){
if (validatePriority(priority)) typePriority = priority;
else
throw new IllegalArgumentException("Priority is not an integer");
}
public void setPriority(int priority){
if(validatePriority(priority)) this.typePriority = priority;
else
throw new IllegalArgumentException("Priority is not an integer");
}
public int getPriorityValue(){
return typePriority;
}
public TaskType getType(){
return this;
}
/**
* priority is represented by an integer value, ranging from 1 to 10
* @param priority
* @return whether the priority is valid or not
*/
private static boolean validatePriority(int priority){
if (priority < 1 || priority >10) return false;
return true;
}
I have tried to test my code and I debugged it and which ever task that is submitted first is executed first.我已经尝试测试我的代码并对其进行了调试,并且首先执行了最先提交的任务。 I noticed that the priority queue size is always 0. maybe I need to add that tasks to the queue in other way then submit?
我注意到优先级队列大小始终为 0。也许我需要以其他方式将该任务添加到队列中然后提交?
here is my test:这是我的测试:
public static final Logger logger = LoggerFactory.getLogger(Tests.class);
@Test
public void Test1() {
CustomExecutor customExecutor = new CustomExecutor();
Callable<Double> callable1 = () -> {
return 1000 * Math.pow(1.02, 5);
};
Callable<String> callable2 = () -> {
StringBuilder sb = new StringBuilder("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
System.out.println(sb);
return sb.reverse().toString();
};
Future<String> reverseTask = customExecutor.submit(callable2, TaskType.IO);
Future<Double> priceTask = customExecutor.submit(() -> {
return 1000 * Math.pow(1.02, 5);
}, TaskType.COMPUTATIONAL);
Task task = Task.createTask(() -> {
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
System.out.println(sum);
return sum;
}, TaskType.COMPUTATIONAL);
Future sumTask = customExecutor.submit(task);
final int sum;
try {
sum = (int)sumTask.get(1, TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new RuntimeException(e);
}
logger.info(() -> "Sum of 1 through 10 = " + sum);
final Double totalPrice;
final String reversed;
try {
totalPrice = priceTask.get();
reversed = reverseTask.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
logger.info(() -> "Reversed String = " + reversed);
logger.info(() -> String.valueOf("Total Price = " + totalPrice));
logger.info(() -> "Current maximum priority = " + customExecutor.getCurrentMax());
customExecutor.gracefullyTerminate();
}
the terminal looks like this:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
55
Jan 09, 2023 12:43:25 AM Ex2Part2.Tests Test1
INFO: Sum of 1 through 10 = 55
Jan 09, 2023 12:43:25 AM Ex2Part2.Tests Test1
INFO: Reversed String = ZYXWVUTSRQPONMLKJIHGFEDCBA
Jan 09, 2023 12:43:25 AM Ex2Part2.Tests Test1
INFO: Total Price = 1104.0808032
Jan 09, 2023 12:43:25 AM Ex2Part2.Tests Test1
INFO: Current maximum priority = 3
which is wrong because the task with priority 2 is executed first insted of the class with priority 1.这是错误的,因为优先级为 2 的任务首先执行优先级为 1 的 class。
If you have an existing list of tasks that you want to submit and ensure that the highest priority task is executed before any others, you have two choices:如果您有要提交的现有任务列表,并确保优先级最高的任务先于其他任务执行,您有两种选择:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.