Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步数据输出流_Java_Multithreading_Locking - Fatal编程技术网

Java 同步数据输出流

Java 同步数据输出流,java,multithreading,locking,Java,Multithreading,Locking,我遇到了一个问题,我有一个在连接到服务器时被实例化的类 我在类中遇到问题的方法如下所示: public void sendData(byte[] dataToSend) throws IOException { sendLock.lock(); int dataLength = dataToSend.length; dout.writeInt(dataLength); dout.write(dataToSend, 0, dataLength); dout

我遇到了一个问题,我有一个在连接到服务器时被实例化的类

我在类中遇到问题的方法如下所示:

public void sendData(byte[] dataToSend) throws IOException {
    sendLock.lock();

    int dataLength = dataToSend.length;
    dout.writeInt(dataLength);
    dout.write(dataToSend, 0, dataLength);
    dout.flush();

    sendLock.unlock();
}
其中,
sendLock
是一个
ReentrantLock
dout=newdataoutputstream(socket.getOutputStream())。对于数量有限的线程,这可以很好地工作,但是如果有大量线程同时调用此方法,则会出现死锁,程序就会停止

这里会发生僵局有什么原因吗?这对我来说没有任何意义,因为我已经移除了所有其他锁以排除它们,而我只剩下这一个了。不管怎样,冲水会导致东西挂起来还是什么?似乎在某个时刻它永远不会释放锁,我不知道为什么

如果我移除锁,就会出现套接字错误,因为一个线程可能会在另一个线程有机会写入之前更改数据长度,等等,但死锁不再发生

作为参考,以下是接收端的run方法:

public void run() {

    while (socket != null) {
        try {
            int dataLength = din.readInt();
            byte[] data = new byte[dataLength];
            din.readFully(data, 0, dataLength);
            Event e = ef.getEvent(data);
            node.onEvent(e);    
        } catch (SocketException se) {
            System.out.println(se.getMessage());
            break;
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage()) ;
            break;
        }
    }
}

您对输出流的某个调用可能会引发异常,并且不会调用
sendLock.unlock()
。所有其他线程将永远等待

检查日志,查看其中一个线程是否引发异常。在代码中,我将使用try-catch-finally块,而不是抛出IOException。这保证了,即使发生了不好的事情,锁也会被释放,以便其他线程可以继续工作

public void sendData(byte[] dataToSend) throws IOException {
    try {
        sendLock.lock();

        int dataLength = dataToSend.length;
        dout.writeInt(dataLength);
        dout.write(dataToSend, 0, dataLength);
        dout.flush();
    }
    finally {
         sendLock.unlock();
    }
}

为什么会有大量线程将数据发送到同一个套接字?注意:您的接收代码应该单独捕获
EOFEException
,而不是记录它:这是正常的。您还应该在
DataOutputStream
和套接字输出流之间添加一个
BufferedOutputStream
。[否则,
flush()。在任何给定的时间都有可能,例如,客户端A和客户端B都在向客户端C发送数据。实际上,现在我想起来了。你是对的,输出流绑定到套接字,不知道我为什么这么想!事实上,这很有帮助,也许正是我搞砸的地方。实际上,我为每个客户机运行了两个线程,一个用于发送,一个用于接收。接收线程可能需要转发上的消息,因此在这一点上,客户端A的发送和接收都可能尝试使用相同的输出流进行发送。。。