summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hugo Benichi <hugobenichi@google.com> 2016-10-13 16:48:42 +0900
committer Lorenzo Colitti <lorenzo@google.com> 2016-12-09 13:42:26 +0900
commitce765b7a51d9452aaa32e43bedeefb7ad200df52 (patch)
tree05084a3b9cd215a6109f1dd615e288d2a9ebd3ce
parent1853f78d768dc44efdc8576302b382ff81a0ffac (diff)
DO NOT MERGE: ConnectivityThread: use lazy holder idiom
This patch changes the way that the ConnectivityThread is lazily instantiated by using the "lazy initialization holder class idiom". The first code point that tries to obtain a reference to the unique ConnectivityThread instance will trigger the creation of the Singleton class, which will guarantee a thread-safe initialization of the static INSTANCE field inside Singleton according to the language specs. This is the Item #71 of Effective Java. The unique static instance of ConnectivityThread is not stored directly inside ConnectivityThread class but is stored in a static nested class. This is to avoid triggering the creation of that unique instance when Zygote does class preloading at phone startup. Otherwise this would lead to Zygote creating a new OS thread during preloading, which is a fatal error. Test: frameworks-wifi tests pass Bug: 26749700 Bug: 28537383 Bug: 32130437 (cherry picked from commit c4fe5d373caa9f53686e4d58e61394dd40558957) Change-Id: If13b363889a8e9396273a90c3d9f9421a48aecbc
-rw-r--r--core/java/android/net/ConnectivityThread.java23
1 files changed, 14 insertions, 9 deletions
diff --git a/core/java/android/net/ConnectivityThread.java b/core/java/android/net/ConnectivityThread.java
index 55c3402bf39d..0b218e738b77 100644
--- a/core/java/android/net/ConnectivityThread.java
+++ b/core/java/android/net/ConnectivityThread.java
@@ -27,25 +27,30 @@ import android.os.Looper;
* @hide
*/
public final class ConnectivityThread extends HandlerThread {
- private static ConnectivityThread sInstance;
+
+ // A class implementing the lazy holder idiom: the unique static instance
+ // of ConnectivityThread is instantiated in a thread-safe way (guaranteed by
+ // the language specs) the first time that Singleton is referenced in get()
+ // or getInstanceLooper().
+ private static class Singleton {
+ private static final ConnectivityThread INSTANCE = createInstance();
+ }
private ConnectivityThread() {
super("ConnectivityThread");
}
- private static synchronized ConnectivityThread getInstance() {
- if (sInstance == null) {
- sInstance = new ConnectivityThread();
- sInstance.start();
- }
- return sInstance;
+ private static ConnectivityThread createInstance() {
+ ConnectivityThread t = new ConnectivityThread();
+ t.start();
+ return t;
}
public static ConnectivityThread get() {
- return getInstance();
+ return Singleton.INSTANCE;
}
public static Looper getInstanceLooper() {
- return getInstance().getLooper();
+ return Singleton.INSTANCE.getLooper();
}
}