我遇到了一个看起来像死锁的问题。
它是一个客户端/服务器应用程序。服务器为每个套接字提供了一个要读取的线程和一个要写入的线程。
读取线程接受客户端命令,处理它,将结果放在队列中,写入线程将其关闭并写出来。
问题是如果读取线程在readLine()上阻塞,而写入线程调用println()它也会阻塞,整个事情都会挂起。提供了Stacktrace,看起来像println()尝试锁定readLine()拥有的资源。
有人可以帮忙吗?
简化示例:
ReadThread:
Socket s;
public void run() {
BufferedReader sin = new BufferedReader(
new InputStreamReader(s.getInputStream()));
while (true) {
String line = sin.readLine();
if (line == null) { break; }
String response = "You sent us this: [" + line + "]";
// add response to queue
}
}
WriteThread:
Socket s;
public void run() {
PrintStream sout = new PrintStream(s.getOutputStream(), true);
while (true) {
String toWrite = getFromQueue();
sout.println(toWrite);
removeFromQueue(toWrite);
}
}
客户的代码:
public static void main(String[] args) throws IOException {
int portNumber = 51192;
Socket s = new Socket("127.0.0.1", portNumber);
String cmd = "ThisIsATest";
PrintStream out = new PrintStream(s.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
out.println(cmd);
String result = in.readLine();
s.close();
System.out.println(result);
}
stacktraces:http://pastebin.com/JnsHUFZn
此示例的完整代码:http://pastebin.com/8RcbxgUw
答案 0 :(得分:1)
您必须拥有Socket
的服务器端SocketChannel
。与这些套接字关联的流由Channels
类分配,它们表现出您描述的行为。堆栈跟踪确认了它。
直接使用java.net.Socket
,即在服务器代码的情况下通过java.net.ServerSocket
。在阻止模式下使用SocketChannel
或ServerSocketChannel
没有任何好处。