【问题标题】:AsyncTask and Memory ObservabilityAsyncTask 和内存可观察性
【发布时间】:2016-09-03 12:50:27
【问题描述】:

我定义了以下类和内部“AsyncTask”(http://developer.android.com/reference/android/os/AsyncTask.html)。

class SomeClassA {

    Long b = 0;

    void executeTask() {
       // executed on main thread.
       b = 1;
       new SomeAsyncTask().execute();
    }

    private class SomeAsyncTask extends AsyncTask<Void, Void, Void> {

        protected Void doInBackground(Void... params) {
           b = 3;
        }

        protected void onPostExecute(Void param) {
           System.out.println(b);
        }
    }
}

我很好奇我在 AsyncTask 的“内存可见性”以及线程安全方面得到了什么保证。据我了解,调用“doInBackground”是在单独的线程中执行的,因此我对“doInBackground”中的“b”所做的任何更改都不能保证在主线程上执行的任何回调中都是“可见的”(例如“onPostExecute()”、“onPreExecute”、“onProgressUpdate”等)。

这是正确的吗?因此,在上面的示例中,“onPostExecute”中的“System.out.println(b)”可以打印 1 或 3,但不能保证。我必须做些什么来保证这种内存可观察性?

在 AsyncTask 网站(上面发布)中,我看到了以下 sn-p。

内存可观察性

AsyncTask 保证所有回调调用都以这样一种方式同步,即以下操作在没有显式同步的情况下是安全的。

  • 在构造函数或onPreExecute()中设置成员字段,并在doInBackground(Params...)中引用。
  • 在doInBackground(Params...)中设置成员字段,在onProgressUpdate(Progress...)和onPostExecute(Result)中引用。

我认为这个“可能”解释了我的困惑,但我不明白这意味着什么。谁能给我解释一下?

【问题讨论】:

    标签: android android-asynctask


    【解决方案1】:

    所以在上面的例子中,“onPostExecute”中的“System.out.println(b)”可以打印1 OR 3,但不能保证

    这将始终打印 3。(如果任务被取消,则不打印)。 onPostExecute 仅在 doInBackground 正确完成时运行。

    谁能给我解释一下?

    本节只是告诉您,在命名方法中使用在各自命名方法中设置的成员是省事的。

    【讨论】:

    • 我认为“doInBackground”是在某个工作线程上调用的,而 onPostExecute() 是在主线程上调用的。由于这些是在两个单独的线程上执行的,难道 doInBackground 中对 b 的写入还没有被刷新到内存中,因此 onPostExecute 正在读取一个陈旧的值吗?
    • 如果这是任意两个线程,是的。但是引用的第二个要点告诉您:doInBackground 中设置的所有内容都可以安全使用onPostExecute。基本上 AsyncTask 保证这不会发生。
    • 啊,我明白了。我查看了这里的源代码 (android.googlesource.com/platform/frameworks/base/+/refs/heads/…),但我不确定该保证是在哪里做出的。代码看起来很简单。
    • “我不确定该保证是在哪里做出的”——保证是由FutureTask 做出的。它保证,计算结果发生在get() 返回之前。 Java 语言规范automatically extends 这保证了其他涉及的变量和操作,这些变量和操作发生在相关线程上读取/写入FutureTask 结果之前/之后。
    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 2015-11-30
    • 2021-11-22
    相关资源
    最近更新 更多