在AsyncTask中,Volatile和Synchronized的作用是什么?

5
在Android SDK中的AsyncTask(内部实现)这里sDefaultExecutor使用volatile关键字声明,并且SerialExecutor中的execute()方法使用synchronized关键字声明。
  1. 由于AsyncTask只能从UI线程执行,而且如果我们执行一个AsyncTask实例,除非前一个实例已经完成执行,否则我们不能再次执行同一个实例。那么这里怎么可能存在多个线程的情况呢?
  2. SerialExecutor为什么有一个ArrayDeque?因为在任何时候,我们只能有一个任务。如果我们创建一个新的AsyncTask实例,那么我们不会得到一个新的ArrayDeque实例吗?它还是只处理一个任务。
  3. ThreadPoolExecutor也是一样的道理。为什么需要线程池,当对于一个AsyncTask实例,我们只有一个任务?一个线程就足够了。
1个回答

2
除非前一个实例已经完成执行,否则我们不能再次执行同一实例。那么为什么这里会有多个线程的情况呢?
例如,有主UI线程和执行器线程。
SerialExecutor为什么有ArrayDeque?因为在任何时候我们只能有一个任务。如果我们创建一个新的AsyncTask实例,那么我们不会得到一个新的ArrayDeque实例,而是只处理一个任务。
并不是只有一个任务可以执行。串行执行器一次只能执行一个任务,但您可以在主线程中排队多个任务,并且它们将在执行器线程中依次执行。
还有其他执行器,比如您稍后提到的线程池执行器。
ThreadPoolExecutor也是同样的情况。为什么需要线程池,当我们可以为特定的AsyncTask实例只有一个任务时,一个线程就足够了呢?
您关于一次只有一个任务的前提是不正确的。线程池执行器用于在单独的线程中同时运行多个异步任务。
任务的排队和多个任务如何出现呢?假设我创建了一个AsyncTask实例并将其执行5次。那么如果其中一个正在运行,另外4个就不会开始。那么在任何情况下,我怎样才能获得多个任务呢?
您只能执行一个AsyncTask实例一次。但是,您可以发布多个不同的AsyncTask实例以供执行。请注意,此类发布操作(execute()等)是异步的,并且在异步任务完成之前返回,您可以在UI线程中运行其他代码,包括发布新的异步任务以供执行。
对于并行执行,只需使用executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ...)。
也是真的,因为SerialExecutor是静态的,所以应用程序中只会使用一个实例,因此需要一个队列吗?
是的,在您的应用程序中只有一个串行执行器,并且它在所有异步任务之间共享。

任务排队和多任务如何出现?假设我创建了一个AsyncTask实例并执行了5次。那么如果其中一个正在运行,其他4个就不会启动。那么我该如何在任何情况下获取多个任务? - Diffy
好的。由于SerialExecutor是静态的,所以它只会在所有AsyncTask实例中使用一次,因此需要一个队列吗? - Diffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接