Java 在ThreadPoolExecutor上实现PriorityQueue

Java 在ThreadPoolExecutor上实现PriorityQueue,java,priority-queue,future,threadpoolexecutor,Java,Priority Queue,Future,Threadpoolexecutor,已经为此挣扎了两天多了 实现了我在这里看到的答案 我的服务:MediaDownloadService public class MediaDownloadService extends Service { private DBHelper helper; Notification notification; HashMap<Integer,Future> futureTasks = new HashMap<Integer, Future>(); final int _

已经为此挣扎了两天多了

实现了我在这里看到的答案

我的服务:MediaDownloadService

public class MediaDownloadService extends Service {

private DBHelper helper;
Notification notification;
HashMap<Integer,Future> futureTasks = new HashMap<Integer, Future>();
final int _notificationId=1;
File file;

@Override
public IBinder onBind(Intent intent) {
    return sharonsBinder;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    helper = new DBHelper(getApplicationContext());
    PriorityExecutor executor = (PriorityExecutor) PriorityExecutor.newFixedThreadPool(3);
    Log.e("requestsExists", helper.requestsExists() + "");
   if(helper.requestsExists()){
        // map of the index of the request and the string of the absolute path of the request
        Map<Integer,String> requestMap = helper.getRequestsToExcute(0);
        Set<Integer> keySet = requestMap.keySet();
        Iterator<Integer> iterator = keySet.iterator();
        Log.e("MAP",requestMap.toString());
        //checks if the DB requests exists
        if(!requestMap.isEmpty()){
            //execute them and delete the DB entry
            while(iterator.hasNext()){
                int iteratorNext = iterator.next();
                Log.e("ITREATOR", iteratorNext + "");
                file = new File(requestMap.get(iteratorNext));
                Log.e("file", file.toString());
                Log.e("thread Opened", "Thread" + iteratorNext);
                Future future = executor.submit(new MyTask(file, this, iteratorNext),10);
                futureTasks.put(iteratorNext, future);
                helper.requestTaken(iteratorNext);
            }
            Log.e("The priority queue",executor.getQueue().toString());
        }else{

            Log.e("stopself", "stop self after this");
            this.stopSelf();
        }
    }
    return START_STICKY;
}
谁能把我从这场噩梦中救出来

我也试着按照这个答案的建议去做

通过添加forNewTask覆盖,只会再次获得强制执行选项,但这次是为了RunnableFuture


我知道我的理解中缺少了一些基本的东西,希望能有一个深入的解释…

通过查看java.util.concurrent.ThreadPoolExecutor的源代码,在提交futures时让它工作起来似乎真的很痛苦。您必须重写感觉是内部的受保护方法,并执行一些讨厌的强制转换

我建议您只需使用
execute
方法即可。这里没有对
Runnable
进行包装,所以它应该可以工作


如果您需要等待工作的结果,我建议您自己实现,以避免弄乱
ThreadPoolExecutor
的内部结构。

sharon gur在最底层的建议是改变

//execute with New comparable task
public void execute(Runnable command, int priority) {
    super.execute(new ComparableFutureTask(command, null, priority));
}

然后在来电者中:

CurrentTask currentTask = new CurrentTask(priority,queue)
RunnableFuture task = enhancedExecutor.execute(currentTask,priority.value)
task?.get()
我有个问题在哪里

RunnableFuture task = myExecutor.submit(currentTask)
task?.get()
导致了一个问题,
currentTask
随后被转换为
FutureTask
,并且不了解我在currentTask中的对象。单独执行,一切都很好。这项技术似乎已经足够用了

因为它工作得很好,但没有生成任何文件

RunnableFuture task = myExecutor.execuute(currentTask)
    task?.get()
所以这就是我如何使它工作(优先级被处理两次)感觉不正确,但工作

当前任务::

class CurrentTask implements Runnable {
    private Priority priority
    private MyQueue queue

    public int getPriority() {
        return priority.value
    }

    public CurrentTask(Priority priority,ReportsQueue queue){
        this.priority = priority
        this.queue=queue
    }

    @Override
    public void run() {
...
}
}
优先权:

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
    }
}
然后你的遗嘱执行人打电话来

public YourExecutor() {

    public YourExecutor() {
        super(maxPoolSize,maxPoolSize,timeout,TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>(1000,new ReverseComparator()))
    }
public your executor(){
公共遗嘱执行人{
超级(maxPoolSize、maxPoolSize、超时、TimeUnit.SECONDS、新的PriorityBlockingQueue(1000,新的ReverseComparator()))
}
因此,在更改为新方法之前,submit点击下面的比较器,而TaskExecutor不会理解.priority?.value作为默认值。execute currentTask就是点击该选项的原因,并且所有操作都有效

public int compare(final Runnable lhs, final Runnable rhs) {

    if(lhs instanceof Runnable && rhs instanceof Runnable){
      // Favour a higher priority
        println "${lhs} vs ${lhs.getClass()}"
      if(((Runnable)lhs)?.priority?.value<((Runnable)rhs)?.priority?.value){
 ...
}

}
public int比较(最终可运行lhs,最终可运行rhs){
if(lhs instanceof Runnable&&rhs instanceof Runnable){
//优先考虑
println“${lhs}vs${lhs.getClass()}”

如果((可运行)左侧)?.priority?.Value我的问题不是等待我的作业完成,而是我想在它们处于队列中时管理它们。例如,我在队列中有项目,我现在需要改进它们的一个优先级,因此我需要有一个对未来对象的引用,以便我可以取消该任务并以更高的优先级重新插入。如果简单地说,我自己实现它,你的意思是自己创建一个线程池?要更改优先级,你需要访问
ComparableFutureTask
,因为这是队列中的内容,而不是
Future
。因此,出于这个目的,你仍然可以使用
executor.execute()
而不是
submit()
.executor.execute()是否将返回一个可比较的未来任务?如果不是,我将如何到达我要取消的任务..?我认为要更改优先级,我必须取消并重新插入任务,并且通过future对象完成取消..或者是吗?@sharongur否否,但由于您已经实现了PriorityExecutor,因此可以在执行时创建一个自定义方法来返回它ng.Brilliant!Absolutey Brilliant!我更改了execute方法以返回ComparableFutureTask,并添加了一个方法以使用包含可比较对象的hashmap的id来增加优先级,然后只需更改其优先级即可。非常感谢!感谢sharon,我在下面扩展了您的评论。相当激烈的主题工作实现可以在这里可以找到
class CurrentTask implements Runnable {
    private Priority priority
    private MyQueue queue

    public int getPriority() {
        return priority.value
    }

    public CurrentTask(Priority priority,ReportsQueue queue){
        this.priority = priority
        this.queue=queue
    }

    @Override
    public void run() {
...
}
}
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
    }
}
public YourExecutor() {

    public YourExecutor() {
        super(maxPoolSize,maxPoolSize,timeout,TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>(1000,new ReverseComparator()))
    }
public int compare(final Runnable lhs, final Runnable rhs) {

    if(lhs instanceof Runnable && rhs instanceof Runnable){
      // Favour a higher priority
        println "${lhs} vs ${lhs.getClass()}"
      if(((Runnable)lhs)?.priority?.value<((Runnable)rhs)?.priority?.value){
 ...
}

}
class  ReverseComparator implements Comparator<ComparableFutureTask>{

  @Override
  public int compare(final ComparableFutureTask lhs, final ComparableFutureTask rhs) {

    if(lhs instanceof ComparableFutureTask && rhs instanceof ComparableFutureTask){

        // run higher priority (lower numbers before higher numbers)
        println "${lhs} vs ${lhs.getClass()} ::: ${lhs.priority}"
      if(((Runnable)lhs)?.priority<((Runnable)rhs)?.priority){
          println "-returning -1"
        return -1;
      } else if (((Runnable)lhs)?.priority>((Runnable)rhs)?.priority){
      println "-returning @@@1"
        return 1;
      } 


    }
    println "-returning ==0 "
    return 0;
  }