问题描述
现在已经为此奋斗了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 wellTesting 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!