同步数据输出流
Synchronizing data output stream
我有一个 class 在连接到服务器时实例化的问题。
我在 class 中遇到问题的方法如下所示:
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 = new DataOutputStream(socket.getOutputStream());
。这适用于有限数量的线程,但如果我有大量线程同时调用此方法,我会遇到死锁,程序就会停止。
这里会出现死锁吗?这对我来说没有意义,因为我已经移除了所有其他锁以排除它们,而我只剩下这个了。无论如何,冲洗是否会导致东西挂起或其他什么?似乎在某些时候它永远不会释放锁,我不确定为什么。
如果我删除锁,我会收到套接字错误,因为一个线程可能会在另一个线程有机会写入之前更改 dataLength,等等。但是死锁不再发生。
作为参考,接收端的运行方法是这样的:
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();
}
}
我有一个 class 在连接到服务器时实例化的问题。
我在 class 中遇到问题的方法如下所示:
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 = new DataOutputStream(socket.getOutputStream());
。这适用于有限数量的线程,但如果我有大量线程同时调用此方法,我会遇到死锁,程序就会停止。
这里会出现死锁吗?这对我来说没有意义,因为我已经移除了所有其他锁以排除它们,而我只剩下这个了。无论如何,冲洗是否会导致东西挂起或其他什么?似乎在某些时候它永远不会释放锁,我不确定为什么。
如果我删除锁,我会收到套接字错误,因为一个线程可能会在另一个线程有机会写入之前更改 dataLength,等等。但是死锁不再发生。
作为参考,接收端的运行方法是这样的:
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();
}
}