实例1
"appscheduling.default" prio=5 tid=55 Blocked
| group="main" sCount=1 ucsCount=0 flags=1 obj=0x13a299c8 self=0xb4000072643f4400
| sysTid=861 nice=-2 cgrp=foreground sched=0/0 handle=0x7261e45cb0
| state=S schedstat=( 1810889629 5149663174 2648 ) utm=144 stm=36 core=4 HZ=100
| stack=0x7261d42000-0x7261d44000 stackSize=1039KB
| held mutexes=
at com.android.server.am.ActivityManagerService$LocalService.updateDeviceIdleTempAllowlist(ActivityManagerService.java:17900)
- waiting to lock <0x0a3ce9ac> (a com.android.server.am.ActivityManagerService) held by thread 209
at com.android.server.DeviceIdleController.updateTempWhitelistAppIdsLocked(DeviceIdleController.java:4642)
at com.android.server.DeviceIdleController.onAppRemovedFromTempWhitelistLocked(DeviceIdleController.java:3406)
at com.android.server.DeviceIdleController.checkTempAppWhitelistTimeout(DeviceIdleController.java:3389)
- locked <0x0f44a533> (a com.android.server.DeviceIdleController)
"binder:739_16" prio=5 tid=209 Blocked
| group="main" sCount=1 ucsCount=0 flags=1 obj=0x14417238 self=0xb4000071ea610800
| sysTid=2490 nice=-2 cgrp=foreground sched=0/0 handle=0x72496eccb0
| state=S schedstat=( 1169444676 11642784307 2992 ) utm=80 stm=36 core=4 HZ=100
| stack=0x72495f5000-0x72495f7000 stackSize=991KB
| held mutexes=
at com.android.server.DeviceIdleController.getUserPowerWhitelistInternal(DeviceIdleController.java:3095)
- waiting to lock <0x0f44a533> (a com.android.server.DeviceIdleController) held by thread 55
at com.android.server.DeviceIdleController.-$$Nest$mgetUserPowerWhitelistInternal(DeviceIdleController.java:0)
at com.android.server.DeviceIdleController$LocalService.getUserPowerWhiteList(DeviceIdleController.java:2387)
at com.android.server.am.ActivityManagerService.appDiedLocked(ActivityManagerService.java:3452)
at com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java:1610)
- locked <0x0a3ce9ac> (a com.android.server.am.ActivityManagerService)
at android.os.IBinder$DeathRecipient.binderDied(IBinder.java:319)
at android.os.BinderProxy.sendDeathNotice(BinderProxy.java:704)
- "appscheduling.default"和"binder:739_16"都处于Blocked状态;
- 第8行:"waiting to lock <0x0a3ce9ac> (a com.android.server.am.ActivityManagerService) held by thread 209"表示当前线程"appscheduling.default"等待的锁<0x0a3ce9ac>被线程号为209的线程即"binder:739_16"持有
- 第12行:"locked <0x0f44a533> (a com.android.server.DeviceIdleController)"表示当前线程"appscheduling.default"持有锁<0x0f44a533>
- 第21行:"waiting to lock <0x0f44a533> (a com.android.server.DeviceIdleController) held by thread 55"表示当前线程"binder:739_16"等待的锁<0x0f44a533>被线程号55的线程即"binder:739_16"持有
- 第26行:"locked <0x0a3ce9ac> (a com.android.server.am.ActivityManagerService)"表示当前线程"binder:739_16"持有锁<0x0a3ce9ac>
"binder:739_16"和"ppscheduling.default"形成死锁
| 线程 | 持有锁 | 等待锁 |
|---|---|---|
| "binder:739_16" | 0x0a3ce9ac | 0x0f44a533 |
| "ppscheduling.default" | 0x0f44a533 | 0x0a3ce9ac |
实例2
"main" prio=5 tid=1 Blocked
| group="main" sCount=1 ucsCount=0 flags=1 obj=0x72a1f738 self=0xb4000076fbcfb6f0
| sysTid=28235 nice=-20 cgrp=top-app sched=0/0 handle=0x791104c4f8
| state=S schedstat=( 3890452885766 171240901531 3639259 ) utm=351045 stm=37999 core=7 HZ=100
| stack=0x7fce606000-0x7fce608000 stackSize=8188KB
| held mutexes=
at com.android.launcher3.model.ModelDbController.createDbIfNotExists(unavailable:0)
- waiting to lock <0x012ab2d9> (a com.android.launcher3.model.ModelDbController) held by thread 19
at com.android.launcher3.model.ModelDbController.migrateGridIfNeeded(ModelDbController.java:307)
at com.android.launcher.settings.LauncherLayoutUtil.forceMigrate(LauncherLayoutUtil.java:100)
at com.android.launcher.settings.SettingsFragment.onAutoFillValueChange(SettingsFragment.java:372)
at com.android.launcher.settings.SettingsFragment.-$$Nest$monAutoFillValueChange(unavailable:0)
at com.android.launcher.settings.SettingsFragment$1.onPreferenceChange(SettingsFragment.java:293)
"launcher-loader" prio=5 tid=19 Waiting
| group="main" sCount=1 ucsCount=0 flags=1 obj=0x12c3dd60 self=0xb4000076fbd3bc00
| sysTid=28255 nice=10 cgrp=top-app sched=0/0 handle=0x7643b98cb0
| state=S schedstat=( 750800081444 29927976968 246727 ) utm=70838 stm=4241 core=7 HZ=100
| stack=0x7643a95000-0x7643a97000 stackSize=1039KB
| held mutexes=
at jdk.internal.misc.Unsafe.park(Native method)
- waiting on an unknown object
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:447)
at java.util.concurrent.FutureTask.get(FutureTask.java:190)
at com.android.launcher3.uioverrides.QuickstepWidgetHolder.destroy(QuickstepWidgetHolder.java:184)
at com.android.launcher3.model.ModelDbController.loadDefaultFavoritesIfNecessary(ModelDbController.java:449)
- locked <0x012ab2d9> (a com.android.launcher3.model.ModelDbController)
at com.android.launcher3.LauncherProvider.call(LauncherProvider.java:294)
at android.content.ContentProvider.call(ContentProvider.java:2682)
- 主线程"main"处于Blocked状态,"launcher-loader"处于Waiting状态
- 第16行: "waiting to lock <0x012ab2d9> (a com.android.launcher3.model.ModelDbController) held by thread 19"表示主线程"main"等待的锁<0x012ab2d9>,被线程号为19的线程即"launcher-loader"持有
- 第55行:"locked <0x012ab2d9> (a com.android.launcher3.model.ModelDbController)"表示当前线程"launcher-loader"持有锁<0x012ab2d9>
- 第43行:"waiting on an unknown object"看出线程"launcher-loader"被FutureTask.get阻塞
src/com/android/launcher3/model/ModelDbController.java
@WorkerThread
public synchronized void loadDefaultFavoritesIfNecessary() {
createDbIfNotExists();
if (LauncherPrefs.get(mContext).get(getEmptyDbCreatedKey(mOpenHelper.getDatabaseName()))) {
LauncherWidgetHolder widgetHolder = mOpenHelper.newLauncherWidgetHolder();
try {
AutoInstallsLayout loader = createWorkspaceLoaderFromAppRestriction(widgetHolder);
if (loader == null) {
loader = AutoInstallsLayout.get(mContext, widgetHolder, mOpenHelper);
}
...
} finally {
widgetHolder.destroy();// line 449
}
}
}
private synchronized void createDbIfNotExists() {
if (mOpenHelper == null) {
...
mDatabaseHelpers.put(mOpenHelper.getDatabaseName(), mOpenHelper);
}
}
public boolean migrateGridIfNeeded() {
createDbIfNotExists();// line 307
InvariantDeviceProfile idp = LauncherAppState.getIDP(mContext);
...
}
src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
@Override
public void destroy() {
try {
MAIN_EXECUTOR.submit(() -> sHolders.remove(this)).get();// line 184
} catch (Exception e) {
Log.e(TAG, "Failed to remove self from holder list", e);
}
}
主线程在调用ModelDbController.migrateGridIfNeeded会调用createDbIfNotExists方法,而createDbIfNotExists方法带synchronized关键字,需要等待持有成员锁的线程"launcher-loader"释放; 而"launcher-loader"线程在持锁过程中调用QuickstepWidgetHolder.destroy时,通过MAIN_EXECUTOR发一个任务给主线程处理,并且要阻塞等待这个任务处理完,此时主线程由于等待"launcher-loader"释放锁处于Blocked状态无法处理该任务,从而导致了主线程和线程"launcher-loader"形成死锁
| 线程 | 持有锁 | 等待锁 |
|---|---|---|
| "main" | 0x012ab2d9 | |
| "launcher-loader" | 0x012ab2d9 | 阻塞等待main线程处理任务 |
sequenceDiagram
main->>launcher-loader: 我等你释放锁
launcher-loader-)main: 我等你任务处理完才能释放锁