For*_*rce 6 java multithreading android synchronized
我正在使用CMU Sphinx语音识别器库(Link to source)来使用synchronized
块.
来自RecognizerTask的一个示例块:
Event mailbox;
[...]
public void start() {
synchronized (this.mailbox) {
this.mailbox.notifyAll();
this.mailbox = Event.START;
}
}
Run Code Online (Sandbox Code Playgroud)
代码工作没有任何问题,但BugFinder提供此警告:
错误:在RecognizerTask.mailbox上进行同步,徒劳地试图保护它
此方法在字段上同步,似乎是试图防止对该字段的同时更新.但是保护一个字段会锁定引用的对象,而不是在字段上.这可能无法提供您需要的互斥,而其他线程可能会在引用的对象上获取锁定(用于其他目的).这种模式的一个例子是:
Run Code Online (Sandbox Code Playgroud)private Long myNtfSeqNbrCounter = new Long(0); private Long getNotificationSequenceNumber() { Long result = null; synchronized(myNtfSeqNbrCounter) { result = new Long(myNtfSeqNbrCounter.longValue() + 1); myNtfSeqNbrCounter = new Long(result.longValue()); } return result; }
说实话,我不太了解错误描述,在这种情况下应该是错误的.全局变量不是字段吗?如果没有,我该如何改进代码呢?
/ edit:这Event.wait()
是调用的唯一部分:
Event todo = Event.NONE;
synchronized (this.mailbox) {
todo = this.mailbox;
/* If we're idle then wait for something to happen. */
if (state == State.IDLE && todo == Event.NONE) {
try {
//Log.d(getClass().getName(), "waiting");
this.mailbox.wait();
todo = this.mailbox;
//Log.d(getClass().getName(), "got" + todo);
} catch (InterruptedException e) {
/* Quit main loop. */
//Log.e(getClass().getName(), "Interrupted waiting for mailbox, shutting down");
todo = Event.SHUTDOWN;
}
}
/* Reset the mailbox before releasing, to avoid race condition. */
this.mailbox = Event.NONE;
}
Run Code Online (Sandbox Code Playgroud)
此代码实际上也使用了一个synchronized
语句.使用它是否有意义?
我认为这不适用于你的情况。您有一个调用notifyAll()
,这意味着其他线程的代码中的某个地方有一个匹配的wait()
调用:
synchronized (this.mailbox) {
this.mailbox.wait();
}
Run Code Online (Sandbox Code Playgroud)
这意味着另一个线程将在等待通知时放弃锁。
您的代码检查器可能会对以下行感到困惑:
this.mailbox = Event.START;
Run Code Online (Sandbox Code Playgroud)
这意味着您可能会同时修改此对象,这样如果另一个线程尝试获取 的锁this.mailbox
,它将看到另一个对象。然而,我确实认为,因为:
this.mailbox
是全球可见的所有线程都应始终具有同步对象的更新视图。