mHandler isn't set from within a synchronized block in Android SDK
Looking through the Android SDK framework source code, I've come across this:
private final class GpsLocationProviderThread extends Thread {
public GpsLocationProviderThread() {
super开发者_开发知识库("GpsLocationProvider");
}
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
initialize();
Looper.prepare();
mHandler = new ProviderHandler();
// signal when we are initialized and ready to go
mInitializedLatch.countDown();
Looper.loop();
}
}
(this is from Froyo's frameworks/base/location/java/com/android/internal/location/GpsLocationProvider.java)
GpsLocationProviderThread
is an inner class of GpsLocationProvider
, and mHandler
is a member instance variable of GpsLocationProvider
. This variable is set from within this thread's run()
method, but no synchronization is applied, and mHandler
is not volatile
.
Why does this work? And even if 99% of the time this does work, it's not always guaranteed to work, and it's certainly not good practice. Am I correct in this understanding, or is there something subtle to this code that I'm misunderstanding?
The thread is created when the provider is created (in its constructor), and the mInitializedLatch
makes sure that the constructor only proceeds once the thread is up and running.
After that point, mHandler is created and valid, and since the Handler class' methods are reentrant, this system should be thread-safe. Handler, after all, is a class that is designed for inter-thread communication.
精彩评论