【问题标题】:Printwriter stucks when calling print method调用打印方法时打印机卡住
【发布时间】:2014-08-14 18:30:07
【问题描述】:

这是一个线程,处理来自服务器端的输入和输出:

    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);
        }
    }

如果我调用打印方法,线程就会卡住。这意味着打印了“之前”,但从未达到“之后”。 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 中。第一个之前已经使用过,并且始终可以正常工作(并且仍然可以)。 另一个是新的并导致此问题。对于每个初始化的连接(具有不同端口的本地主机),肯定只有一个写入器。

客户端 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,则打印机不会被卡住!

【问题讨论】:

    标签: java printing client printwriter


    【解决方案1】:

    虽然我没有看到声明,但读取器和写入器对象(在 readFromSocket() 方法中引用)看起来可能是成员变量。我会担心读者和作者不是线程安全的。我会考虑删除这些成员变量,看看你是否仍然对作者有问题。

    【讨论】:

    • 嗨,是的,它都是成员变量。但是仅在这两个方法中调用了 writer(datafetcher 仅用于初始化和 sendMessage)。在 sendMessage 中,我现在添加了“同步(编写器)”,即使它不应该是两个不同的线程调用该方法。所以线程安全不是问题,对吧?
    猜你喜欢
    • 2014-03-13
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多