这是在Android应用中。我们有一个类来管理与服务器的套接字通信,并且该类具有用于发送和接收消息的线程。
我们偶尔会在方法中获得IllegalMonitorStateException
,然后将消息发送给处理程序,然后通知发送线程'这样它就会从处理程序读取消息并将其发送到服务器:
java.lang.IllegalMonitorStateException: object not locked by thread before notify()
at java.lang.Object.notify(Native Method)
at com.company.appname.package.ServerConnection.sendMessageToServer(ServerConnection.java:448)
at com.company.appname.package.ServerConnection.sendMessageToServer(ServerConnection.java:418)
at com.company.appname.package.ServerConnection.gotResponse(ServerConnection.java:403)
at com.company.appname.package.ServerConnection.gotConnected(ServerConnection.java:349)
at com.company.appname.package.ServerEventHandler.handleMessage(ServerEventHandler.java:59)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
异常发生在以下代码中的mMessageSendThreadForServer.notify();
。
public class MessageSendThread extends Thread {
...
}
public class ServerConnection {
...
private final Object mMessageSendThreadForServerLock = new Object();
private MessageSendThread mMessageSendThreadForServer;
...
private void sendMessageToForServer(String msg)
{
...
// Wake the sending thread
synchronized(mMessageSendThreadForServerLock)
{
synchronized(mMessageSendThreadForServer)
{
mMessageSendThreadForServer.notify();
}
}
}
...
}
我发现的所有文档和其他问题都表明这不应该导致IllegalMonitorStateException
。我已经看到很多问题,人们在synchronize
内更改了对象,但我们在synchronize
内所做的只是调用notify()
。
任何想法都表示赞赏。我很难过。
答案 0 :(得分:2)
您提供的代码段没有任何问题,但可以修改它以防止它。
试试这个片段,看看会发生什么。它可以防止另一个线程更改引用。
...
// Wake the sending thread
synchronized(mMessageSendThreadForServerLock)
final MessageSendThread sendThread = mMessageSendThreadForServer;
synchronized(sendThread)
{
sendThread.notify();
}
}
...