问题
我已经为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然后返回唤醒锁定”代码。出于测试的目的,断言语句是JUnit断言方法,所以我认为我们可以假设它们是正确的。
代码的问题是这样的:最后的断言 - assertTrue(hasWakeLock())
- 似乎每隔几周就失败一次,几乎没有解释。这意味着我在这里有三个可能的问题:(1)从来没有从PowerManager(2)中检索到唤醒锁,我有一个并发问题,在极少数情况下,在后置条件之前但在调用{{ 1}},或者(3)acquire()
有时是错误的。
调查问题
如上所述,我正在调查/调查过三个可能发生的潜在问题:
假设1:未返回唤醒锁:
如果是这种情况,那么我会看到一个空指针异常。不可能是那样。
假设2:我有一个并发问题:
刚刚进行的所有参与获取和发布acquire()
的地方的正式验证证明强烈地让我相信事实并非如此。在我的证据有问题的情况下,我可能会遇到并发问题,但它确实是阴险的,很难找到。
假设3:WakeLock.acquire()有问题,despite what the documentation says有时无法获取锁:
我不喜欢这个假设,因为对于所有的Android用户,除了我自己之外的某人现在必须注意到这一点,它几乎总是开发人员的代码,而不是库或操作系统代码,是有缺陷的。然后,陌生人的事情发生了,这可能是一个真正的Android bug,虽然很少展出。如果这个假设为真,那么acquire()根本就不会获取唤醒锁,这可以解释我所看到的行为。
那么StackOverflow,可能导致这个问题的原因是什么?你觉得怎么了?我错过了一些明显的东西,或者这可能是Android唤醒锁的真正问题吗?
答案 0 :(得分:0)
这似乎确实是一个并发问题。我忽略了这样一个事实:可以从一个单独的线程中的非同步位置调用相关方法 - 这是高度多线程环境中的一个明显问题!