gpt4 book ai didi

android - 使用 AsyncTask 在线程之间传递的实例变量的行为是什么?

转载 作者:行者123 更新时间:2023-11-29 18:31:32 26 4
gpt4 key购买 nike

我知道在多个线程之间访问共享实例变量是不安全的(除非该变量被声明为 volatile 并且正确地synchronized)。我试图理解使用 Android 的 AsyncTask 将共享实例变量传递给后台线程的语义。 .

考虑以下代码:

public class Example {
ContentValues contentValues;

public void start() {
contentValues = new ContentValues();
contentValues.put("one", 1);
new MyAsyncTask().execute(contentValues);
contentValues.put("two", 2);
}


class MyAsyncTask extends AsyncTask<ContentValues, Void, Boolean> {
@Override
public void onPreExecute() {
contentValues.put("three", 3);
}

@Override
protected Boolean doInBackground(ContentValues... cvs) {
ContentValues cv = cvs[0];
return cv == contentValues;
}
}
}

我们对 doInBackground() 中局部变量 cv 的状态了解多少?具体来说,

  • 保证其中包含哪些键值对。

  • 其中可能包含哪些键值对?

  • doInBackground() 会返回什么?

最佳答案

如果您使用的是基本线程,则成员字段将不会同步,并且无法像您提到的那样保证可见性。

在使用 AsyncTask 的情况下,它取决于 AsyncTask 框架的实现。

"one", 1肯定会在,因为它放在线程创建之前。

如果我们检查 AsyncTask 的源代码我们可以找到如下评论:

* <h2>Memory observability</h2>
* <p>AsyncTask guarantees that all callback calls are synchronized in such a way that the following
* operations are safe without explicit synchronizations.</p>
* <ul>
* <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
* in {@link #doInBackground}.
* <li>Set member fields in {@link #doInBackground}, and refer to them in
* {@link #onProgressUpdate} and {@link #onPostExecute}.
* </ul>

所以 "three", 3 会在那里,因为它是在 onPreExecute 中添加的。

这也意味着 ContentValues contentValues; 字段将在 doInBackground 点同步,因此该方法将返回 true。

尽管我不认为 "two", 2 项一定会存在,因为该代码与异步线程并行运行。可能存在,但不一定。种族和能见度方面都会对此产生影响。

关于android - 使用 AsyncTask 在线程之间传递的实例变量的行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56013092/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com