我有一些关于通用线程框架(当然是针对特定数量的工作)的使用与使用许多asyntasks的问题。
我想知道为小作业提供多个asyntasks是否更好,当作业需要更长时间时有一个处理程序线程,或者更好的是让自己拥有一个通用作业,通用作业具有建立在其上的通知系统正在运行的线程(或子类,相同的故事)。
我的想法是创建处理不同作业的线程,而不事先知道哪些作业。这就是为处理不同的通用作业创建一种小框架的方向。
例如,我的方法是在下面的代码的方向:
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;
}
}
此处任务是所有作业扩展的抽象基类。
然后在这个线程或该类的子类之上可以是一个观察者,它通知作业/任务出错的时间。
到目前为止,据我所知,我的方法的优点和缺点是这样的:
主题:
优点:
1.长时间运营。
2.集中。
3.可扩展。
一旦你对它进行了适当的测试,它就能顺利运行。
缺点
1.复杂的架构。
2.难以维护。
3.小型工作的过度工程。
AsynTask:
优点
1.易于使用。
2.适合短期操作工作。
3.易于维护/理解。
缺点
1.无法扩展那么多,你需要坚持doInBackground和onPostExecute。
2.不适合长期作业。
如果我错过了什么,请纠正我。
最后的问题是,当架构在很多请求中变得有点大时,短时间,长时间,最好不要尝试制作一个可以处理它的通用框架而不是用它来处理它在那里asynctasks,也许在其他部分处理,等等?
答案 0 :(得分:0)
AsyncTask应该用于简短操作。从官方文档:
AsyncTask旨在成为Thread和Handler的辅助类 并不构成通用的线程框架。 AsyncTasks 理想情况下应该用于短期操作(几秒钟的时间) 大多数。)如果你需要保持线程长时间运行, 强烈建议您使用提供的各种API java.util.concurrent包,如Executor,ThreadPoolExecutor和 FutureTask。
因此,如果操作设计时间超过几秒,建议使用并发包。例如,操作是存储文件,图片,登录等
然而,Asynctask也有一些限制,因为它可以在下面的链接中看到:
AsyncTask limitations
可以同时运行多少任务的数量有限。由于AsyncTask使用具有最大工作线程数的线程池执行程序(128),并且延迟任务队列具有固定大小10.如果您尝试执行超过138个AsyncTasks,则应用程序将因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)之后,并行异步通信的数量取决于设备具有的处理器数量:
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线程和后台运行的任务。此外,为了在SD卡上异步加载/保存图片,可以使用不同的库,如Picasso或Glide。