这是一个Thread,它处理来自服务器端的输入和输出:
public void run() {
Thread currentThread = Thread.currentThread();
while (!currentThread.isInterrupted()) {
SocketChannel socketChannel = null;
try {
socketChannel = serverSocketChannel.accept();
readFromSocket(socketChannel);
} catch (ClosedByInterruptException e) {
// closed due to interrupt
connected = false;
} catch (IOException e) {
if (!isInterrupted()) {
e.printStackTrace();
}
connected = false;
} finally {
quietClose(socketChannel);
}
}
}
/**
* Reads an message from socketChannel and executes
* {@link AbstractServer#handleMessage(String)}. Initializes
* {@link #writer} with the socketChannel.
*
* @param socketChannel
* @throws IOException
*/
public void readFromSocket(SocketChannel socketChannel) throws IOException {
reader = null;
writer = null;
try {
reader = new BufferedReader(new InputStreamReader(socketChannel.socket().getInputStream()));
if (writer == null) {
writer = new PrintWriter(socketChannel.socket().getOutputStream(), true);
}
String message;
while ((message = reader.readLine()) != null) {
handleMessage(message);
}
} catch (ClosedByInterruptException e) {
throw e;
} catch (IOException e) {
e.printStackTrace();
} finally {
quietClose(reader);
quietClose(writer);
}
}
如果我调用print方法,则线程会被卡住。这意味着打印“之前”,但永远不会达到“之后”。 printwriter的CheckError方法返回false!
/**
* Sends a message to the client.
*
* @param message
*/
public void sendMessage(final String message) {
System.out.println("before");
writer.print(message);
System.out.println("after");
writer.flush();
}
它位于AbstractServer中,由两个不同的服务器使用。第一个已经使用过,并且总是在没有问题的情况下工作(并且仍然可以)。 另一个是新的并导致这个问题。绝对只有一个编写器用于每个连接(都有不同端口的localhost)初始化。
客户端Datafetcher如下所示:
protected void fetchDataFromSocket() {
if (socketDataFetcher != null) {
socketDataFetcher.interrupt();
}
socketDataFetcher = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String message = socketConnection.readLine();
if (messageHandler != null) {
messageHandler.handleMessage(message);
}
} catch (IOException e) {
Thread.currentThread().interrupt();
}
}
}
});
socketDataFetcher.start();
}
它与另一个只与实际上不会导致问题的微小变化有关的几乎相同。 打印机的行为可能是什么原因?
编辑:如果我没有在客户端启动socketDataFetcher,则打印机不会被卡住!
答案 0 :(得分:0)
虽然我没有看到声明,但是reader和writer对象(在readFromSocket()方法中引用)看起来可能是成员变量。我会担心读者和作者不是线程安全的。我会看到有关删除这些成员变量的信息,看看你是否还有编写器的问题。