在ThreadPoolExecutor上实现PriorityQueue [英] implementing PriorityQueue on ThreadPoolExecutor

查看:111
本文介绍了在ThreadPoolExecutor上实现PriorityQueue的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在已经为此奋斗了2天以上.

Been struggling with this for over 2 days now.

实现了我在这里看到的答案 指定Java中的任务顺序执行

implemented the answer I saw on here Specify task order execution in Java

public class PriorityExecutor extends ThreadPoolExecutor {

public PriorityExecutor(int corePoolSize, int maximumPoolSize,
                        long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
    super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
//Utitlity method to create thread pool easily
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new PriorityExecutor(nThreads, nThreads, 0L,
            TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>());
}
//Submit with New comparable task
public Future<?> submit(Runnable task, int priority) {
    return super.submit(new ComparableFutureTask(task, null, priority));
}
//execute with New comparable task
public void execute(Runnable command, int priority) {
    super.execute(new ComparableFutureTask(command, null, priority));
}
}

public class ComparableFutureTask<T> extends FutureTask<T>
    implements
    Comparable<ComparableFutureTask<T>> {

volatile int priority = 0;

public ComparableFutureTask(Runnable runnable, T result, int priority) {
    super(runnable, result);
    this.priority = priority;
}
public ComparableFutureTask(Callable<T> callable, int priority) {
    super(callable);
    this.priority = priority;
}

@Override
public int compareTo(ComparableFutureTask<T> o) {
    return Integer.valueOf(priority).compareTo(o.priority);
}
}

我使用的Runnable:MyTask

The Runnable I use: MyTask

public class MyTask implements Runnable{

 public MyTask(File file, Context context, int requestId) {
    this._file = file;
    this.context = context;
    this.requestId = requestId;
}

@Override
public void run() {
      // some work
    } catch (IOException e) {
        Log.e("Callable try", post.toString());

    }
}

我的服务:MediaDownloadService

My service: 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;
}

请继续在此行上获取错误: 未来的未来= executor.submit(new MyTask(file,this,iteratorNext),10);

keep getting an error on this line : Future future = executor.submit(new MyTask(file, this, iteratorNext),10);

即使是executor.submit();假设要返回一个我不断得到的对象

Even tho an executor.submit(); suppose to return a future object i keep getting

Caused by: java.lang.ClassCastException: java.util.concurrent.FutureTask cannot be cast to java.lang.Comparable
        at java.util.concurrent.PriorityBlockingQueue.siftUpComparable(PriorityBlockingQueue.java:318)
        at java.util.concurrent.PriorityBlockingQueue.offer(PriorityBlockingQueue.java:450)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1331)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:81)
        at com.vit.infibond.test.PriorityExecutor.submit(PriorityExecutor.java:26)
        at com.vit.infibond.test.MediaDownloadService.onStartCommand(MediaDownloadService.java:65)

有人能把我从这场噩梦中救出来吗?

Can anyone save me from this nightmare?

我也尝试做这个答案 在ThreadPoolExecutor中测试PriorityBlockingQueue

I tried doing as this answer suggest as well Testing PriorityBlockingQueue in ThreadPoolExecutor

通过添加forNewTask重写仅再次获得强制执行,但这一次是RunnableFuture.

by adding the forNewTask override only to get casting execption again but this time for RunnableFuture.

我了解我的理解中缺少一些基本知识,并且希望您能进行深入的解释...

I understand something basic is missing on my understanding and would appreciate a depth explanation...

推荐答案

通过查看java.util.concurrent.ThreadPoolExecutor的源代码,提交期货时使此功能正常工作似乎很痛苦.您必须重写感觉内部的受保护方法并进行一些讨厌的强制转换.

By looking at the source code for java.util.concurrent.ThreadPoolExecutor it seems to be a real pain to get this working when submitting futures. You have to override protected methods that feels internal and do some nasty casts.

我建议您直接使用execute方法. Runnable没有包装,所以应该可以使用.

I suggest you simply use the execute method instead. There is no wrapping of the Runnable going on there so it should work.

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

If you need to wait for the results of your jobs I suggest implementing that on your own to avoid having to mess around with the ThreadPoolExecutor internals.

这篇关于在ThreadPoolExecutor上实现PriorityQueue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆