2017-01-21 15 views
2

我有,我发动负责分派是他们在消息的线索下面的服务代码。什么是与“龙监控器竞争事件”

 public void run() { 
      while (! Thread.interrupted()) { 
      try { 
       Message msg = null; 
       synchronized (_queue) { 
       if (_queue.size() == 0) { 
        _queue.wait(10000); 
       } 

       if (_queue.size() != 0) { 
        msg = _queue.poll(); 
       } 

       if (msg != null) { 
        _dispatcher.dispatch(msg); 
       } 
       } 
      } 
      catch (InterruptedException i) {    } 
      catch (Exception e) {    } 
      } 
     } 
    public void add (final Message m){ 
    if (m == null) 
     return; 
    synchronized (_queue){ 
     _queue.add(m); 
     _queue.notify(); 
    } 
    } 

但是这个问题时,该代码在我的Android模拟器上运行,我收到很多警告,如下所示:

Long monitor contention event with owner method=void com.foo.PrioritizedMessageQueue.run() from PrioritizedMessageQueue.java:58 waiters=0 for 585ms 

对我而言,这似乎是编写队列处理器的最有效方式。当没有消息要处理时,处理线程将一直等到添加一个消息,“add”将通知任何正在等待的线程为什么新消息被添加到队列中。我的想法是,当没有消息存在时(因为它被阻止),调度线程不会使用最少的资源。

但是,有一个原因,为什么android发布此警告,但我不知道为什么。很显然,我的线程被阻止了很长时间,但为什么会这样呢?这不是更高效,因为它在等待时不会使用任何CPU周期吗?

另外,我是否应该担心android可能会因为阻塞时间过长而杀掉我的线程?我会恨我的线程被杀但不是服务。如果我的服务被杀死了,我可以处理,但我无法处理那一个被杀的线程。

回答

2

在调用_dispatcher.dispatch之前,您应该释放队列上的锁定。否则,在辅助线程正在处理消息时,试图呼叫_queue.add的外部线程被阻塞。

调整花括号是所有需要的。这里是你的run线程函数调整后允许在放弃_queue监视器后调用dispatch

public void run() { 
     while (! Thread.interrupted()) { 
     try { 
      Message msg = null; 
      synchronized (_queue) {  // acquire the queue lock 
      if (_queue.size() == 0) { 
       _queue.wait(10000); 
      } 

      if (_queue.size() != 0) { 
       msg = _queue.poll(); 
      } 
      }       // release the queue lock 

      if (msg != null) { 
      _dispatcher.dispatch(msg); 
      } 
     } 
     catch (InterruptedException i) { 
     } 
     catch (Exception e) { 
     } 
     } 
    }