繁体   English   中英

Java中的多线程阻塞

[英]Multithread blocking in Java

我有类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;

}

我也有侦听器类(扩展线程),它侦听来自服务器的传入消息。 消息到达时,侦听器线程读取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(),并且服务器显示它发送的消息包含服务器上所有房间的列表,方法也从侦听器线程中调用,但是listRooms()从对象LobbyView调用(扩展了扩展JPanel的View) )附加到ClientWindow的对象上(扩展了JFrame),所以它是不同的线程。 而且我不知道为什么它被阻止了。 因此,监听器显然无法调用processMessage,但我不知道为什么或对Java中的线程有一些错误的理解:D

编辑:这也表明侦听器线程由于某种原因而被阻止...

问题是它会永远等待。 我发送@refresh消息后再也不会调用processMessage()

在我看来,您的listRooms()调用正在对Client对象进行wait ,而processMessage(...)方法正在对Listener对象调用notify() 为了使notify()唤醒另一个线程,它必须在同一对象实例上。 当您拥有synchronized方法时,它将锁定this对象实例。

这两个对象必须共享一个公共锁定对象,以便能够相互发出信号。 一种执行此操作的方法是将一个锁对象传递到ClientListener ,然后执行以下操作:

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

...

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

编辑:这也表明侦听器线程由于某种原因而被阻止...

我不知道为什么Listener会被阻止,但这不是因为notify()调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM