[英]WakeLock-related Mandelbug: does WakeLock.acquire() always succeed?
问题
我已经为Android开发了相当一段时间。 我开发的程序之一大量使用了WakeLocks 。 它通常是完美的(通常一次需要几天或几周,这是程序的要求),但是我很少注意到此代码中的特殊行为:
acquireWakeLock(wakeLockManager)
// Preconditions
assertFalse("Wake lock already acquired.", hasWakeLock());
assertNotNull("Wake lock manager not provided.", wakeLockManager);
// Acquire a wake lock.
wakeLock = wakeLockManager.newPartialWakeLock(DEBUG_TAG);
wakeLock.acquire();
// Postconditions
assertTrue("Wake Lock should be held!", hasWakeLock());
hasWakeLock()
仅返回(wakeLock != null && wakeLock.isHeld())
的结果,而wakeLockManager.newPartialWakeLock(DEBUG_TAG)
封装标准的“获取PowerManager,然后返回唤醒锁”代码。 出于测试目的,assert语句是JUnit assert方法,因此我认为我们可以假定它们是正确的。
代码的问题是这样的:最终的断言assertTrue(hasWakeLock())
-每隔几周就会失败,几乎没有解释。 这意味着我这里有三个可能的问题:(1)从来没有从PowerManager检索唤醒锁(2)我有一个并发问题,在极少数情况下,该问题仅在后置条件之前但在调用acquire()
,或者(3) acquire()
有时有问题。
问题调查
如上所述,我正在调查/调查的问题可能有三个:
假设1:唤醒锁未返回 :
如果是这种情况,那么我会看到一个空指针异常。 不可能是那样。
假设2:我有一个并发问题 :
对参与获取和发布wakeLock
的所有场所的刚刚进行的正式验证证明,使我坚信事实并非如此。 如果我的证明有错误,那么我可能会遇到并发问题,但是那确实是隐蔽的,很难找到。
假设3:WakeLock.acquire()有错误, 尽管文档说了什么,但有时它可能无法获取锁 :
我不喜欢这个假说,因为所有的Android用户提供有一个人除了自己一定已经注意到了这一点,它几乎总是开发人员的代码,而不是库或OS的代码,这是错误的。 再说一次,奇怪的事情发生了,这可能是一个真正的Android错误,尽管很少出现。 如果这个假设是正确的,那么acquire()根本就不会获得唤醒锁,这将解释我所看到的行为。
那么StackOverflow,可能是什么引起这个问题? 你觉得错什么? 我是否缺少明显的东西,或者这可能是Android唤醒锁的真正问题?
看来这确实是一个并发问题。 我忽略了以下事实:可以从单独线程中的非同步位置调用相关方法-在高度多线程的环境中,这是一个明显的问题!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.