我有类Client和方法,名为listRooms()。
public synchronized RoomInfo[] listRooms() {
sendMessage(new Message("@refresh"));
try {
System.out.println("#1");
wait();
System.out.println("#2");
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
if( m_RoomListMessage == null )
return null;
RoomInfo[] rooms = new RoomInfo[ m_RoomListMessage.getInteger(0) ];
for(int i=0; i<rooms.length; i++) {
rooms[i] = new RoomInfo(
m_RoomListMessage.getString(3*i + 1),
m_RoomListMessage.getBoolean(3*i + 2),
m_RoomListMessage.getInteger(3*i+3)
);
}
return rooms;
}
我还有类Listener(extends Thread),它监听来自服务器的传入消息。当消息到达时,侦听器线程读取Message(使用ObjectInputStream),然后调用next方法。
public synchronized void processMessage(Message aMessage) {
if( aMessage.type.equals("@roomlist") ) {
m_RoomListMessage = aMessage;
notify();
System.out.println("notificiran xD");
return;
}
MessageHandler handler = m_MessageHandlers.get(aMessage.type);
if( handler == null ) {
System.out.println("No MessageHandler for: " + aMessage.type);
return;
}
handler.onMessage(aMessage);
}
问题是它永远等待。我发送@refresh消息之后永远不会调用processMessage(),我的服务器显示它发送的消息包含服务器上所有房间的列表,也从Listener线程调用方法但是从对象LobbyView调用listRooms()(扩展View扩展了JPanel )附加到ClientWindow的对象(扩展JFrame),所以它是不同的线程。我不知道为什么会被阻止。所以Listener显然不能调用processMessage,但我不知道为什么或者我对Java中的线程有一些错误的理解:D
编辑:它还表示监听器线程由于某种原因被阻止...
答案 0 :(得分:3)
问题是它永远等待。在发送@refresh消息
之后,从不调用processMessage()
在我的listRooms()
方法调用wait
Client
时,我processMessage(...)
调用了notify()
Listener
对象对象。对于notify()
唤醒另一个线程,它必须在同一个对象实例上。当您拥有synchronized
方法时,它会锁定this
对象实例。
这两个对象必须共享一个公共锁定对象才能相互发信号。一种方法是将锁定对象传入Client
和Listener
,然后执行以下操作:
synchronized (commonLock) {
commonLock.wait();
}
...
synchronized (commonLock) {
commonLock.notify();
}
编辑:它还表示监听器线程由于某种原因被阻止...
我不知道为什么Listener
会被屏蔽,但这不是因为notify()
电话。