1

我在配备 S40 的诺基亚设备上遇到问题(但在 S60 上没有)。问题是这样的:当您从同步块中调用discoveryAgent 的cancelInquiry 方法时,它会挂起。它实际上应该回调inquiryCompleted。代码只是冻结-永远不会进入inquiryCompleted方法。如果完成了相同的事情,但不是在同步块内完成 - 一切正常。问题是我需要同步块,以便其中的所有内容在多线程应用程序中原子执行。

这就是我的 DiscoveryListener 的样子:

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 上),从不调用 queryCompleted!(当我在调用discoveryAgent的cancelInquiry之前放置哔哔声时,它发出哔哔声。当我在那个调用之后放置它时,它没有到达那里。那是因为调用不会返回,直到它调用inquiryCompleted并且该调用不会发生)

问题是什么?如果这是 S40 的 cancelInquiry 的 impl'n 中的错误,我该如何解决?我必须同步,因为事情是并行完成的(例如,我的代码可能会开始查询,然后可能会取消它。在它被取消时,startInquiry 可能正在运行,deviceDiscovered 可能正在运行,inquiryCompleted 可能正在运行,并且当然,与其中任何一个并行,传入的 cancelInquiry 可能正在运行。

我试图将inquiryCompleted 分离到另一个侦听器实例中,换句话说,我没有调用discoveryAgent.cancelInquiry(this),而是调用了discoveryAgent.cancelInquiry(anotherInstance),希望调用“anotherInstance”中的inquiryCompleted,但不,它挂起方式也是如此。

有什么建议么?提前致谢

4

1 回答 1

0

我不喜欢这种方法,但是,因为你不能使用同步......繁忙的等待循环怎么样?http://en.wikipedia.org/wiki/Busy_wait

你可以试试下面的代码:

    私有线程取消线程;

    公共布尔取消(){
        同步(这个){
            而(取消线程!= null){
                尝试 { Thread.sleep(100); } 捕捉(异常 e){}
            }
            cancelThread = Thread.currentThread();
        }

        // 做你的事

        取消线程=空;// 返回前
    }

于 2012-04-19T11:54:10.173 回答