WEB开发网
开发学院手机开发Android 开发 Android2.1源码中的一个bug 阅读

Android2.1源码中的一个bug

 2010-10-14 06:16:00 来源:本站整理   
核心提示:Log.i(TAG, "Telephony Registry");ServiceManager.addService("telephony.registry",new TelephonyRegistry(context));后经仔细分析ActivityManagerService

Log.i(TAG, "Telephony Registry");

ServiceManager.addService("telephony.registry",

new TelephonyRegistry(context));

后经仔细分析ActivityManagerService的main方法源码

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

发现有多线程同步的问题。main方法中有代码如下:

AThread thr = new AThread();

thr.start();

synchronized (thr) {

while (thr.mService == null) {

try {

thr.wait();

} catch (InterruptedException e) {

}

}

}

……………

thr.mRead = true;

notifyAll();

我们非常容易看出这段代码的意思是启动一个线程thr,然后等待线程线程初始化完成thr.mService变量再继续执行。

那么我们再分析一下AThread的run方法。

Looper.prepare();

android.os.Process.setThreadPriority(

android.os.Process.THREAD_PRIORITY_FOREGROUND);

ActivityManagerService m = new ActivityManagerService();

synchronized (this) {

mService = m;

notifyAll();

}

synchronized (this) {

while (!mReady) {

try {

wait();

} catch (InterruptedException e) {

}

}

}

Looper.loop();

表面上看来这段代码也没有问题。先初始化mService通知ActivityManagerService的主线程(notifyAll()),然后等待主线程执行,并重置了mRead之后,再继续执行。

问题出在notifyAll之后,多线程编程最重要的就是要注意竞争关系。假如AThread调用notifyAll之后,主线程没有得到调度,还是在调度AThread将会怎么样呢?第一次AThread的第一次wait成功返回(对主线程的通知,被他自己给截获了),第二次就加锁。这时开始调度主线程,主线程wait发现还是没有通知,那就继续等待下去,变成了死锁。本人对Java不是非常熟悉,以上面的方式使用wait/notify /notifyAll方法肯定是不正确的。如果我的理解有问题,请Java达人赐教。

为了确保代码的修改量最小,我选用了权宜之计。解决方法是在notifyAll之后sleep一下,sleep之后当前线程将会释放调度权。修改后的代码如下:

上一页  5 6 7 8 9 10 11  下一页

Tags:Android 源码 一个

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接