Issue
I understand that it's not safe to access a shared instance variable between multiple threads (unless the variable is declared volatile
and properly synchronized
). I'm trying to understand the semantics of passing a shared instance variable to a background thread using Android's AsyncTask
.
Consider the following code:
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;
}
}
}
What do we know about the state of the local variable cv
in doInBackground()
? Specifically,
Which key-value pairs are guaranteed to be in it.
Which key-value pairs might be in it?
What will
doInBackground()
return?
Solution
If you were using a basic thread the member field would not be synchronized and the visibility won't be guaranteed as you mention.
In case of using AsyncTask it depends on the implementation of the AsyncTask framework.
"one", 1
will definitely be there because it is put before the thread is created.
If we check the source code of AsyncTask we can find the following comment:
* <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>
So "three", 3
will be there since it was added in onPreExecute
.
Also it means that the ContentValues contentValues;
field will be synchronized at the point of doInBackground
, so the method will return true.
Though I don't think that the "two", 2
item is guaranteed to be there, since that code is run in parallel with the async thread. Might be there, but not necessarily. Both race and visibility aspects can influence that.
Answered By - TpoM6oH
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.