"Long monitor contention event" 有什么问题
What's the issue with "Long monitor contention event"
我有以下服务代码,我在其中启动负责调度消息的线程。
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 可能会因为阻塞时间过长而终止我的线程?我讨厌我的线程被杀死而不是服务。如果我的服务被终止,我可以处理,但我不能只处理一个线程被终止。
您应该在调用 _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) {
}
}
}
我有以下服务代码,我在其中启动负责调度消息的线程。
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 可能会因为阻塞时间过长而终止我的线程?我讨厌我的线程被杀死而不是服务。如果我的服务被终止,我可以处理,但我不能只处理一个线程被终止。
您应该在调用 _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) {
}
}
}