我在装有 S40 的诺基亚设备上遇到问题(但在 S60 上没有)。问题是这样的:当您从同步块中调用发现代理的cancelQuery方法时,它挂了。它实际上应该回调查询已完成。代码只是冻结 - 永远不会进入查询已完成方法。如果完成了同样的事情,但不是从同步块中完成的 - 一切正常。问题是我需要同步块,以便其中的所有内容都在多线程应用程序中原子地执行。
这是我的发现侦听器的样子:
public class DeviceDiscoverer implements DiscoveryListener {
private Object thisCannotBeInterruptedByOtherBlocksLikeIt=new Object();
private boolean stiiInCycle;
private DiscoveryAgent discoveryAgent;
public boolean cancel() { //called from some controller in mid discovery
//synchronized(thisCannotBeInterruptedByOtherBlocksLikeIt) //problem when this is uncommented
{
if (stillInCycle) {
//<some logic>
discoveryAgent.cancelInquiry(this);
//<more logic>
}
}
}
public void inquiryCompleted(int inquiryStatus) { //this is a callback in response to cancel or normal ending
Beeper.beep(); //this makes the phone make a sound
}
// <some irrelevant methods here. some have synchronized blocks like the one above>
}
当您在 S40 和 S60 上运行上述代码时,同步语句被注释掉,并调用 cancel() 方法,立即调用 inquiryCompleted 方法,您会听到哔哔声。但是,如果您取消注释同步语句,您会在 S60 上听到哔哔声,但在 S40(至少在第 5 版 fp1 上),永远不会调用查询已完成!(当我在调用发现代理的取消查询之前发出哔哔声stmt时,它发出了哔哔声。 当我在那个电话之后放置它时,它没有到达那里。 那是因为呼叫没有返回,直到它调用查询已完成并且该调用没有发生)
问题出在哪里? 如果这是 S40 的取消查询的 IMPL'n 中的错误,我该如何解决它?我必须同步,因为事情是并行完成的(例如,我的代码可能会启动查询然后,可以取消它。在取消时,startInquiry 可能正在运行,设备发现可能正在运行,查询已完成可能正在运行,当然与其中任何一个并行,传入的 cancelInquiry可能正在运行。
换句话说,我试图将查询完成到另一个侦听器实例中,而不是调用discoveryAgent.cancelInquiry(this)我称之为discoveryAgent.cancelInquiry(otherInstance),希望查询在"另一个实例"中完成将被调用,但不,它也以这种方式挂起。
有什么建议吗?提前致谢
我不喜欢这种方法,但是,由于您不能使用同步...繁忙的等待循环怎么办?http://en.wikipedia.org/wiki/Busy_wait
您可以尝试以下代码:
私有线程取消线程; 公共布尔值取消() { 同步(这) { 而 (取消线程 != 空) { try { Thread.sleep(100); } catch(Exception e) {} } cancelThread = Thread.currentThread(); } 做你的事情 取消线程 = 空;返回前 }