【问题标题】:generic thread framework vs asynctask通用线程框架 vs asynctask
【发布时间】:2015-10-10 07:34:27
【问题描述】:

我对通用线程框架的使用(当然对于特定数量的作业)与许多异步任务的使用有一些疑问。
我想知道是否最好为小型作业设置许多异步任务,当作业需要更长的时间时使用处理程序线程,或者最好有一个通用线程自己拥有通用作业和构建在顶部的通知系统正在运行的线程(或子类,同样的故事)。

我的想法是创建处理不同作业的线程,而无需事先知道哪些作业。这朝着创建一种用于处理不同通用作业的小型框架的方向发展。
例如,我的方法朝着下面的代码方向发展:

    public (abstract if you want to extend and add something on top) class WorkerThread extends Thread {

    private static final String TAG = WorkerThread();
    private List<WorkTask> syncQueue = new ArrayList< WorkTask >();
    private boolean clearQueue = false;
    public WorkerThread() {

    }


    public void stop(boolean clear) {
        clearQueue = clear;
        this.stopWorker = true;
    }

    public void addTask(WorkerTask task) {
        synchronized (syncQueue) {
            if (task != null && !getSynQueue().contains(task)) {
                getSynQueue().add(task);
            }
        }
    }

    @Override
    public void run() {
        while (!stopWorker) {
            WorkerTask task = null;
            synchronized (syncQueue) {
                if (!getSynQueue().isEmpty()) {
                    task = getSynQueue().get(0);
                }
            }
            if (task != null) {
                try {
                    task.run();
                    synchronized (syncQueue) {
                        if (!getSynQueue().isEmpty()) {
                            getSynQueue().remove(task);
                            //notify something/someone
                        }
                    }
                } catch (Exception e) {
                    Log.e(TAG, "Error in running the task." + e.getMessage());
                    synchronized (syncQueue) {
                       //again u can notify someone
                    }
                } finally {
                    //here you can actually notify someone of success
                }
            }
        }
        if(clearQueue){
           getSynQueue().clear();
        }
    }
    private List<WorkerTask> getSynQueue() {
        return this.syncQueue;
    }
}

这里的任务是所有作业扩展的抽象基类。
然后在这个线程或这个类的子类之上可以是一个观察者,它在作业/任务出现问题时通知。 到目前为止,据我所知,我的方法的优缺点如下:
Thread

优点:
1.长时间操作。
2. 集中化​​。
3. 可扩展。
4. 正确测试后,它将顺利运行。

缺点
1. 复杂的架构。
2. 难以维护。
3. 过度设计小工作。

异步任务:

优点
1、使用方便。
2. 适合短时间操作的工作。
3. 易于维护/理解。

缺点
1. 不能扩展那么多,你需要坚持 doInBackground 和 onPostExecute。
2.不适合长时间操作的工作。

如果我遗漏了什么,请纠正我。
最后一个问题是,当架构变得有点大,有很多请求时,短时间,长时间,尝试制作一个可以同时处理它的通用框架而不是在那里使用异步任务来做不是更好吗,也许其他部分的handlerthread等?

【问题讨论】:

    标签: android multithreading generics android-asynctask


    【解决方案1】:

    AsyncTask 应该用于短操作。来自官方文档:

    AsyncTask

    AsyncTask 被设计成一个围绕 Thread 和 Handler 的辅助类 并且不构成通用线程框架。异步任务 理想情况下应用于短操作(几秒钟在 大多数。)如果您需要保持线程长时间运行, 强烈建议您使用由 java.util.concurrent 包,例如 Executor、ThreadPoolExecutor 和 未来任务。

    因此,如果操作被设计为超过几秒,建议使用并发包。例如,操作是,存储文件、图片、登录等。
    但是,Asynctask 也有一些限制,如以下链接所示:
    AsyncTask limitations

    可以同时运行多少个任务是有限制的。由于 AsyncTask 使用具有最大工作线程数 (128) 的线程池执行程序,并且延迟任务队列的大小固定为 10。如果您尝试执行超过 138 个 AsyncTask,应用程序将因 java.util.concurrent.RejectedExecutionException 而崩溃。


    此外,在 Api 1.6 和 3.0 之间,无法自定义 AsyncTask。它可以并行运行任务,但无法进行自定义。一种 在 API 3.0 和 API 4.3.1 之间,默认的固定延迟队列大小为 10,最小任务数为 5,最大任务数为 128。但是,在 API 3.0 之后,可以定义自己的执行器。 因此,如果您有至少 16 个任务要运行,则前 5 个将启动,接下来的 10 个将进入队列,但从第 16 个开始将分配一个新的工作线程。在 4.4(kitkat) 版本之后,并行 asynctask 的数量取决于设备拥有的处理器数量:

    private static final int CPU_COUNT =    Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);
    

    上述细节使 AsyncTask 仅在非常特定的情况下可用,例如从存储加载图像或文件。

    通用线程框架(或库)可以轻松扩展和定制。库的示例是易于定制的 RxJava。使用 RxJava 可以指定任务在 UI 线程和后台运行。此外,为了在 sdcard 上异步加载/保存图片,可以使用不同的库,如 Picasso 或 Glide。

    【讨论】:

      猜你喜欢
      • 2014-07-09
      • 2014-08-30
      • 1970-01-01
      • 2012-10-02
      • 1970-01-01
      • 1970-01-01
      • 2016-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多