【问题标题】:Volatile and Synchronized in AsyncTaskAsyncTask 中的可变和同步
【发布时间】:2023-03-26 22:55:01
【问题描述】:

在AsyncTask(在Android SDK中)here的内部实现中,sDefaultExecutorvolatile关键字声明,SerialExecutor中的execute()方法也用synchronized关键字声明。

  1. 现在因为 AsyncTask 只能从 UI 线程执行,而且如果 我们执行AsyncTask 的实例,我们不能执行相同的 除非前一个实例已完成执行,否则再次实例化。 那么这里怎么会出现多线程的情况呢?
  2. 为什么SerialExecutorArrayDeque?因为有时我们 只能有一项任务。如果我们创建一个AsyncTask 的新实例, 那么我们不会再得到一个ArrayDeque 的新实例吗? 要处理一个任务?
  3. ThreadPoolExecutor 也是如此。为什么是线程池 当AsyncTask 的特定实例需要时,我们可以有 只有一个任务?一个线程就足够了。

【问题讨论】:

    标签: java android multithreading android-asynctask


    【解决方案1】:

    除非前一个实例已完成执行,否则我们不能再次执行同一个实例。那么这里怎么会有多线程的情况呢?

    例如,有主 UI 线程和执行器线程。

    为什么 SerialExecutor 有一个 ArrayDeque?因为一次我们只能完成一项任务。如果我们创建了一个新的 AsyncTask 实例,那么我们会不会得到一个新的 ArrayDeque 实例,同样只有一个 Task 需要处理?

    只有一项任务是不正确的。串行执行器一次只能执行一个任务,但您可以在主线程中排队多个任务,并在执行器线程中一个一个地执行。

    除了串行执行器之外,还有其他的执行器,比如你后面提到的线程池执行器。

    ThreadPoolExecutor 也是如此。为什么对于 AsyncTask 的特定实例,我们只能有一个 Task 时需要线程池?一个线程就足够了。

    您一次只完成一项任务的前提是不正确的。线程池执行器对于在不同线程中同时运行多个异步任务很有用。

    任务和多项任务的排队是如何产生的?假设我创建了一个 AsyncTask 实例并执行了 5 次。然后,如果一个正在运行,其他 4 个将不会启动。那么在任何情况下我怎样才能获得多个任务?

    您只能执行一次AsyncTask 的一个实例。但是您可以发布多个不同的AsyncTask 实例以供执行。请注意,此类发布操作(execute() 等)是异步的,并在异步任务完成之前返回,您可以在 UI 线程中运行其他代码,包括发布新的异步任务以供执行。

    对于并行执行,只需使用executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ...)

    是否也因为 SerialExecutor 是静态的,所以在所有 AsyncTask 实例中只会使用它的一个实例,因此需要一个队列?

    是的,您的应用中只有一个串行执行器,它在所有异步任务之间共享。

    【讨论】:

    • 任务和多任务的排队是如何产生的?假设我创建了一个 AsyncTask 实例并执行了 5 次。然后,如果一个正在运行,其他 4 个将不会启动。那么在任何情况下我怎样才能获得多个任务?
    • 好的。是否也因为 SerialExecutor 是静态的,所以在所有 AsyncTask 实例中只会使用它的一个实例,因此需要一个队列?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多