AsyncTask的关于执行人和的PriorityBlockingQueue实现问题 [英] AsyncTask on Executor and PriorityBlockingQueue implementation issue

查看:135
本文介绍了AsyncTask的关于执行人和的PriorityBlockingQueue实现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在的<一个浪潮href="http://stackoverflow.com/questions/12039596/asynctask-on-executor-and-priorityblockingqueue">this SO质疑并从<一个多提示href="http://stackoverflow.com/questions/7792767/priority-threadpoolexecutor-in-java-android">another 之一,我试图实施的AsyncTask 变体可优先任务。

On the wave of this SO question and with many hints from another one, I'm trying to implement an AsyncTask variant with tasks that can be prioritized.

在我的 CustomAsyncTask I类有:

public abstract class CustomAsyncTask<Params, Progress, Result> {

    private static int CORE_POOL_SIZE = 1;
    private static int MAXIMUM_POOL_SIZE = 1;

    private static final int KEEP_ALIVE = 1;

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            return new Thread(r, "CustomAsyncTask #" + mCount.getAndIncrement());
        }
    };

    private static final BlockingQueue<DownloadTask> pPoolWorkQueue =
            new PriorityBlockingQueue<DownloadTask>(10, new DownloadTasksComparator());

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Executor PRIORITY_THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, (PriorityBlockingQueue) pPoolWorkQueue, sThreadFactory);

   //...
}

比较:

public class DownloadTasksComparator implements Comparator<DownloadTask> {

    @Override
    public int compare(DownloadTask arg0, DownloadTask arg1) {
        int res;

        if (arg0 == null && arg1 == null) {
            res = 0;
        } else if (arg0 == null) {
            res = -1;
        } else if (arg1 == null) {
            res = 1;
        }

        res = arg0.getPriority() - arg1.getPriority();

        return res;
    }
}

DownloadTask 类扩展 CustomAsyncTask 我有一个优先级整型字段和 getPriority()方法。

In the DownloadTask class extending CustomAsyncTask I have a priority Integer field and a getPriority() method.

我打电话的任务执行为:

I'm calling the tasks execution as:

DownloadTask dt = new DownloadTask(..., PRIORITY_NORMAL, ...);
dt.executeOnExecutor(CustomAsyncTask.PRIORITY_THREAD_POOL_EXECUTOR);

本作品:如果池的大小为1,则下载Get逐一执行;如果池大小为2,等等。

This works: if the pool sizes are 1, the downloads get executed one by one; if pool size is 2, etc.

请注意:优先级整数有任意值:

note: priority Integers have arbitrary values:

public static final int PRIORITY_HIGH = 10;
public static final int PRIORITY_NORMAL = 1;

但是,如果我所说的任务:

But if I call the tasks as:

DownloadTask dt = new DownloadTask(..., PRIORITY_HIGH, ...);
dt.executeOnExecutor(CustomAsyncTask.PRIORITY_THREAD_POOL_EXECUTOR);

我有一个 java.lang.ClassCastException:my.pkg.name.CustomAsyncTask $ 3不能转换为my.pkg.name.DownloadTask

然后

at my.pkg.name.DownloadTasksComparator.compare(DownloadTasksComparator.java:1)
at java.util.concurrent.PriorityBlockingQueue.siftUpUsingComparator(PriorityBlockingQueue.java:334)
at java.util.concurrent.PriorityBlockingQueue.offer(PriorityBlockingQueue.java:447)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at my.pkg.name.CustomAsyncTask.executeOnExecutor(CustomAsyncTask.java:494)
at my.pkg.name.GetDownloadTaskListener$1.finishDownload(GetDownloadTaskListener.java:180)
at my.pkg.name.DownloadTask.onPostExecute(DownloadTask.java:330)
at my.pkg.name.DownloadTask.onPostExecute(DownloadTask.java:1)
at my.pkg.name.CustomAsyncTask.finish(CustomAsyncTask.java:536)
at my.pkg.name.CustomAsyncTask.access$0(CustomAsyncTask.java:532)
at my.pkg.name.CustomAsyncTask$InternalHandler.handleMessage(CustomAsyncTask.java:549)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

所有的 AndroidRuntime

我真的没有线索......

I really don't have a clue...

修改:在这一点上,我裹着一个小的Eclipse项目实现的东西正是大应用程序相同的方式和同样的问题受到影响。它借用 CustomAsyncTaskComparator CustomAsyncTask 一字不差。没有视觉反馈给。该应用程序的进步只是一些LogCat中输出。但它给的想法。当两个以上的任务入队,应用程序功能界别。

EDIT: At this point, I've wrapped a small Eclipse project that implements things exactly the same way of the bigger application and suffers from the same issue. It borrows CustomAsyncTaskComparator and CustomAsyncTask verbatim. No visual feedback is given. The app's progress is just some LogCat output. But it gives the idea. When more than two tasks are enqueued, the app FCs.

https://www.dropbox.com/s/lrg4kscgw3f1xwr /ConcurrentTest.tar.gz

https://www.dropbox.com/s/lrg4kscgw3f1xwr/ConcurrentTest.tar.gz

推荐答案

正如你可能已经注意到了,同时期待通过的AsyncTask 实现,它在内部使用了 FutureTask提供处理后台任务,而这正是被移交到执行程序和潜在的排队它的工作队列。既然你已经得出自己的实现,你可以替换 FutureTask提供与持有引用一个自定义的衍生的AsyncTask ,从你的比较实施访问。

As you may have noticed while looking through the AsyncTask implementation, it internally uses a FutureTask to handle the background task, and that is what gets handed on to the Executor and potentially queued on it's work queue. Since you are already deriving your own implementation, you could replace the FutureTask with a custom derivative that holds a reference to the AsyncTask, to be accessed from your Comparator implementation.

此外,而不是替换的执行程序自定义默认静态的AsyncTask 导数,你应该使用的在你的子类executeOnExecutor()方法,以便它可以在一个通用的方式使用。

Also, instead of replacing the default static Executor of your custom AsyncTask derivative, you should instead use the executeOnExecutor() method in your subclasses so that it can be used in a generic manner.

这篇关于AsyncTask的关于执行人和的PriorityBlockingQueue实现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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