clzola
clzola

Reputation: 2025

Multithread blocking in Java

I have class Client and method called 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;

}

I also have class Listener (extends Thread) which listens for incoming messages from server. As the message arrives listener thread reads Message (using ObjectInputStream) and then calls next method.

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);
}

The problem is it waits forever. processMessage() is never called after I sent @refresh message and my server shows that it sent message containing list of all rooms on server, also method is called from Listener thread but listRooms() is called from object LobbyView (extends View which extends JPanel) attached to object of ClientWindow (extends JFrame), so it is different thread. And I don't know why is it blocked. So Listener obviously cannot call processMessage but I don't know why or I have some wrong understanding of threads in Java :D

EDIT: It also indicates that Listener thread is blocked for some reason...

Upvotes: 0

Views: 95

Answers (1)

Gray
Gray

Reputation: 116828

The problem is it waits forever. processMessage() is never called after I sent @refresh message

Looks to me that your listRooms() call is doing a wait on the Client object while your processMessage(...) method is calling notify() on a Listener object. For the notify() to wake up the other thread it must be on the same object instance. When you have a synchronized method, it is locking on the this object instance.

These two objects must share a common lock object to be able to signal each other. One way you can do this is to pass in a lock object into both the Client and the Listener and then do something like:

 synchronized (commonLock) {
     commonLock.wait();
 }

...

 synchronized (commonLock) {
     commonLock.notify();
 }

EDIT: It also indicates that Listener thread is blocked for some reason...

I don't know why the Listener would be blocked but it's not because of the notify() call.

Upvotes: 3

Related Questions