調査しているいくつかのオープンソースコードで、次の状況が発生しています。これは、次のことを行う同期ブロックを使用しています。
- プライベートブールインスタンス変数hasListenerをtrueに設定します
- インスタンス変数内に例外を格納する大きなtryブロックを使用してwait()を実行するメソッドを呼び出します
- hasListenerをfalseに設定します
- 以前に保存された例外をスローします
同じクラスに、まったく同じことを行う別の同様のメソッドがあります。
理論的には、これにより、入力時にhasListenerがfalseになるようにする必要があります。しかし、どういうわけか、例外が下部にスローされています(//?とマークされたコメントを参照)。これは、メソッドに入り、hasListenerがtrueであるためです。hasListenerが設定されている場所が他になく、デフォルト値がfalseであることを確認しました。waitFirstMessage()の下部で例外をスローすると、変数がfalseに戻されなくなるという考えられる状況はありますか?他に考えられる状況はありますか?
ログからは、正当な例外が発生しているように見え(「操作を完了するまでの時間が超過しました」)、その時点から例外(//?)がかなり頻繁にスローされます。
protected void waitFirstMessage (int msgId) throws LDAPException {
synchronized (this) {
if (!hasListener) {
hasListener = true;
while ((request != null) && (request.id == msgId) &&
(m_exception == null) && (response == null)) {
waitForMessage();
}
hasListener = false;
// Network exception occurred ?
if (m_exception != null) {
LDAPException ex = m_exception;
m_exception = null;
throw ex;
}
} else {
//?
throw new LDAPException();
}
}
}
private void waitForMessage () throws LDAPException {
try {
if (request.timeToComplete > 0) {
long timeToWait = request.timeToComplete -
System.currentTimeMillis();
if (timeToWait > 0) {
wait(timeToWait);
if (notified) {
notified = false;
} else if (request.timeToComplete < System.currentTimeMillis()) {
// Spurious wakeup before timeout.
return;
} else {
request = null;
m_exception = new LDAPException(
"Time to complete operation exceeded",
LDAPException.LDAP_TIMEOUT);
}
} else {
request = null;
m_exception = new LDAPException(
"Time to complete operation exceeded",
LDAPException.LDAP_TIMEOUT);
}
} else {
wait();
notified = false;
}
} catch (InterruptedException e) {
m_exception = new LDAPInterruptedException("Interrupted LDAP operation");
} catch (Exception e) {
m_exception = new LDAPException("Unexpected exception while waiting for response",
LDAPException.OTHER, e.getMessage());
}
}
編集
わかりました、私の質問は間違っていたことがわかりました。ログの取得元である本番環境で現在実行されているバージョンは、私が見ていたコードよりもわずかに早く、誰かがこの問題に明確に対処しています。以前のバージョンでは、waitForMessage()
メソッドは例外をスローしていました。これらは中断waitFirstMessage(int msgId)
しhasListener
ていて、falseに設定されることはありませんでした。宇宙は再び理にかなっています。
返信ありがとうございます。次に、この修正を本番環境に移行する必要があります。